{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss\fcharset0 Helvetica;}}
{\*\generator Msftedit 5.41.21.2500;}\viewkind4\uc1\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\lang1033\f0\fs24 <?xml version="1.0" encoding="UTF-8"?>\par
\par
<Module>\par
 <ModulePrefs title="Reply Using Twitter"\par
              author="Cisco"\par
              author_email="help@cisco.com"\par
              scrolling="true"\par
              height="700">\par
   <Require feature="dynamic-height"/>\par
   <Require feature="settitle"/>\par
   <Require feature="minimessage"/>\par
   <Require feature="setprefs"/>\par
   <Locale messages="https://10.68.37.114/templates/reply/../../messages/en_US.xml"/>\par
 </ModulePrefs>\par
 <Content type="html">\par
   <![CDATA[\par
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">\par
<html>\par
<head>\par
\par
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">\par
\par
<style type="text/css">\par
\par
body \{\par
\tab font-family:"Lucida Grande",Verdana,sans-serif;color:#000000;\par
\tab font-size:12px;\par
\tab position:absolute;z-index:0;top:0px;left:0px;\par
\tab background-color:transparent; \par
\tab width:100%;\par
\tab margin:0;padding:0;border:0;\par
\}\par
\tab   \par
a:link             \{color:#333399;text-decoration:underline;\} \par
a:visited          \{color:#993366;text-decoration:underline;\} \par
br                 \{line-height:8px;clear:both;\}\par
\par
\par
th \{\par
background-color:#eef3f8;\par
border-bottom:1px solid #eef3f8;\par
border-top:1px solid #eef3f8;\par
border-left:1px solid #eef3f8;\par
border-right:1px solid #FFFFFF;\par
font-weight:normal;\par
line-height:16px;\par
padding-left:2px;\par
padding-right: 2px;\par
text-align:left;\par
vertical-align:middle;\par
\}\par
\par
td \{\par
line-height:16px;\par
padding: 1px;\par
vertical-align: top;\par
\}\par
\par
td input[type="checkbox"] \{\par
\tab margin-left: 6px;\par
\}\par
\par
.transferBox \{\par
\tab margin-top: 15px;\par
\tab width: 480px;\par
\}\par
\par
.transferBox select \{\par
\tab height: 200px;\par
\tab width: 200px;\par
\}\par
\par
.transferBox div \{\par
\tab float: left;\par
\tab margin-left: 2px;\par
\tab margin-right: 2px;\par
\}\par
\par
.transferBox .controls \{\par
\tab width: 40px;\par
\tab padding-top: 30px;\par
\}\par
\par
.transferBox .controls .spacer \{\par
\tab display: block;\par
\tab height: 25px;\par
\}\par
\par
.transferBox div button \{\par
\tab width: 100%;\par
\tab margin-left: 0 auto ;\par
\tab margin-right: 0 auto ;\par
\}\par
\par
.layer \{\par
\tab clear: both;\par
\}\par
\par
button \{\par
         cursor:pointer;\par
\}\par
\par
legend \{\par
    font-size:14px;\par
    font-weight:bold;\par
    position:relative;\par
    top:-.4em;\par
\}\par
\par
select:disabled\{\par
\tab background-color:#DCDCDC;\par
\}\par
\par
div.floatLeft \{\par
\tab float: left;\par
\tab margin: 5px 0 0 10px;\par
\tab width: 500px;\par
\}\par
\par
.layerHeadingFloat \{\par
\tab float: left;\par
\tab margin: 0;\par
\tab padding: 0 0 5px 0;\par
\}\par
\par
.toolbar \{\par
\tab float: right;\par
\tab margin-right: 5px;\par
\}\par
\par
.toolbar IMG \{\par
\tab border:0;\par
\tab width: 20px;\par
\tab height: 20px;\par
\tab padding-left: 3px;\par
\tab padding-top: 1px;\par
\tab cursor: pointer;\par
\}\par
\par
.hidden \{\par
\tab display: none;\par
\}\par
\par
div.floatRight \{\par
\tab float: right;\par
\tab margin: 7px 50px 0 0;\par
\}\par
\par
span.floatLeft \{\par
\tab float: left;\par
\tab margin: 10px 0 0 10px;\par
\}\par
\par
span.floatRight \{\par
\tab float: right;\par
\tab margin: 7px 50px 0 0;\par
\}\par
\par
.title \{\par
\tab border-top: thin outset #407bb3;\par
\tab font-weight:normal;\par
\tab line-height:16px;\par
\tab text-align:left;\par
\tab vertical-align:middle;\par
\tab display: inline-block;\par
\tab width: 100%;\par
\tab height: 22px;\par
\tab padding-top: 1px;\par
\}\par
\par
.layerHeading \{\par
\tab font-size:16px;\par
\tab font-weight:normal;\par
\}\par
\par
.info, .success, .warning, .error, .systemError, .systemWarning\{\par
\tab width: 100%;\par
    border: 1px solid;\par
\tab margin: 5px 0px;\par
\tab padding:5px;\par
    background-repeat: no-repeat;\par
    background-position: 10px center;\par
\}\par
.info \{\par
\tab border-color: #00529B;\par
    background-color: #BDE5F8;\par
\}\par
.success \{\par
    border-color: #4F8A10;\par
    background-color: #DFF2BF;\par
\}\par
.warning \{\par
    border-color: #9F6000;\par
    background-color: #FEEFB3;\par
\}\par
.systemWarning \{\par
    border-color: #9F6000;\par
    background-color: #FEEFB3;\par
\}\par
.error \{\par
    border-color: #D8000C;\par
    background-color: #FFBABA;\par
\}\par
\par
.systemError \{\par
    border-color: #D8000C;\par
    background-color: #FFBABA;\par
\}\par
\par
.settingsLabel \{\par
\tab font-weight:bold;\par
\}\par
\par
\par
textarea.errorHighlight\{background-color:red\}\par
\par
#summaryData \{\par
        \par
\tab\tab overflow-x:hidden;\par
\tab\tab padding: 2px;\par
\}\par
\par
#detailsForm \{\par
\tab\tab overflow-x:hidden;\par
\tab\tab padding: 2px;\par
\}\par
\par
.content \{\par
\tab overflow-y:auto;\par
\tab height: 500px;\par
\}\par
\par
.gadgetHeader \{\par
\tab overflow-y:hidden;\par
\tab padding-bottom: 5px;\par
\}\par
\par
.footer \{\par
\tab padding-top: 10px;\par
\}\par
\par
#postList \{\par
\tab\tab overflow-x:hidden;\par
\tab\tab overflow-y:hidden;\par
\tab\tab padding: 0px 2px 2px 2px;\tab\par
\}\par
\par
input.error \{\par
\tab border: 1px solid red;\par
\}\par
\par
.postEntry:hover .statecontrols \{\par
\tab /* opacity: 1.0; */\par
\}\par
\par
.statecontrols \{\par
\tab display: inline-block;\par
\tab float: right;\par
    border:0;\par
    margin-right:0px;\par
    margin-left: auto;\par
\tab margin-top: 2px;\par
\tab margin-bottom: 2px;\par
\tab /* opacity: 0.01; */\par
\}\par
\par
.statecontrols IMG \{\par
    border:0;\par
    width:18px;\par
    height:18px;\par
    margin-right:0px;\par
    padding: 0px 5px 0px 5px;\par
    cursor: pointer;\par
\}\par
\par
IMG.feedStatusIcon \{\par
\tab border:0;\par
\tab width:16px;\par
\tab height:16px;\par
\tab margin-right:0px;\par
\tab padding: 0px 2px 0px 1px;\par
\}\par
\par
IMG.serverStatusIcon \{\par
\tab border:0;\par
\tab width:16px;\par
\tab height:16px;\par
\tab margin-right:0px;\par
\tab padding: 0px 0px 0px 1px;\par
\tab vertical-align:bottom;\par
\}\par
\par
.throughputGradient \{\par
\tab border:0;\par
\tab width:130px;\par
\tab height:30px;\par
\tab vertical-align:middle;\par
\tab display:inline-block;\par
\}\par
\par
.throughputGraph \{\par
\tab width:130px;\par
\tab height:30px;\par
\tab position:relative;\par
\tab right:133px;\par
\tab vertical-align:middle;\par
\tab display:inline-block;\par
\}\par
\par
.contactstate \{\par
    float:right;\par
\tab vertical-align: middle;\par
\tab height: 22px;\par
\tab display: inline;\par
\tab margin: 2px 2px 2px 2px;\par
\}\par
\par
.updated, .author \{\par
\tab float: left;\par
\tab vertical-align: middle;\par
\tab display: inline;\par
\tab font-size:10px;\par
\tab color: #222222;\par
\}\par
\par
.trainingResponse, .tagResponse \{\par
\tab text-align: center ;\par
\tab padding: 1px 5px;\par
\tab border: 1px solid;\par
\tab border-color: #4F8A10;\par
\tab background-color: #DFF2BF;\par
\tab margin: 2px 2px 2px 2px;\par
\tab float: left;\par
\}\par
\par
.tagResponse \{\par
\tab margin-left: 5px;\par
\}\par
\par
.verticalSeparator \{\par
\tab display: inline-block;\par
\tab border-left: 2px solid;\par
\tab border-color: #8499A2;\par
\tab height:18px;\par
\}\par
\par
.trainingHeading \{\par
\tab\par
\tab padding-right: 40px;\par
\}\par
\par
.tags \{\par
\tab clear: both;\par
\tab margin-top: 5px;\par
\tab width: 100%;\par
\}\par
\par
.proxy \{\par
\tab margin-top: 5px;\par
\tab width: 380px;\par
\}\par
\par
.tags input[type="text"] \par
\{\par
  width: 100px;\par
\}\par
\par
.proxy label \par
\{\par
  display: inline-block;\par
  float: left;\par
  min-width: 10em;\par
  text-align: left;\par
  margin: 4px;\par
\}\par
\par
.proxyExcludeList\par
\{ \par
  height:250px;\par
  overflow:auto;\par
 \}\par
\par
/*\par
   Set proxy settings link style so it looks the same\par
   even after it is clicked\par
*/\par
.proxySettingsLink\par
\{ \par
  float: right;\par
  margin-bottom: 5px;\par
  margin-right: 10px;\par
 \}\par
\par
a.proxySettingsLink:link, a.proxySettingsLink:visited\par
\{ \par
  color:#333399;\par
  text-decoration:underline;\par
 \}\par
\par
.proxy input[type="text"]\par
\{ \par
  margin: 3px;\par
  width: 200px;\par
 \} \par
\par
.proxy input[type="checkbox"]\par
\{ \par
  margin: 3px;\par
 \}\par
\par
.proxySettings:disabled\par
\{ \par
  background-color:#DCDCDC;\par
 \}\par
\par
.postEntry:hover input[type="text"]\par
\{\par
\tab border: 1px solid;\par
\tab border-color: #407BB3;\par
\tab\par
\}\par
\par
.postEntry input[type="text"] \{\par
\tab border: 1px solid;\par
\tab border-color: #407BB3;\par
\}\par
\par
.postEntry button \{\par
\par
\}\par
\par
.postEntry:hover \{\par
\tab background-color: #EEF3F8;\par
\tab width: 100%;\par
\}\par
\par
.postEntry a, .postEntry a:link, .postEntry a:visited \{\par
\tab color:#333399;\par
\tab text-decoration: none;\par
\tab font-size: 13px;\par
\}\par
\par
.postEntry a:hover \{\par
\tab text-decoration: underline;\par
\}\par
\par
.postEntry \{\par
\tab width: 100%;\par
\tab padding-bottom: 5px;\par
\}\par
\par
.suggestedTagsWrapper \{\par
\tab\par
\tab height: 20px;\par
\}\par
\par
.suggestedTags\par
\{\tab\par
\}\par
\par
.tagSuggestion \{\par
\tab color:#555599;\par
\tab text-decoration: none;\par
\}\par
\par
\par
.tagSuggestion:hover \{\par
\tab text-decoration: underline;\par
\tab cursor: pointer;\par
\}\par
\par
.postEntry:hover .suggestedTags \{\par
\}\par
\par
.currentTags \{\par
\}\par
\par
.postEntry:hover .addTags \{\par
  visibility: inherit;\par
/*\tab opacity: 1.0;\par
\tab -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";*/\par
\}\par
\par
.postEntry .addTags \{\par
  visibility: hidden;\par
/*\tab opacity: 0.01;\par
\tab -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";*/\par
\}\par
\par
.summary \{\par
\tab width: 100%;\par
\tab margin-bottom: 2px;\par
\}\par
.tag,.proxyExcludeTag \{\par
\tab display: inline-block;\par
\tab border-color: #AEB8BC;\par
\tab background:none repeat scroll 0 0 #DFF4FF;\par
\tab border:1px solid #A7CEDF;\par
\tab\par
\tab margin-bottom: 3px;\par
\tab margin-right: 3px;\par
\tab padding:2px 3px 2px 3px;\par
\tab\par
\tab -moz-border-radius: 5px;\par
\tab -webkit-border-radius: 5px;\par
\tab -khtml-border-radius: 5px;\par
\}\par
\par
#pendingResultsContainer \{\par
\tab height: 20px;\par
\tab width: 100%;\par
\tab display: inline-block;\par
\tab margin-top: 2px;\par
\tab padding-bottom: 5px;\par
\}\par
\par
#pendingResults \{\par
\tab display: inline-block;\par
\tab border-color: #AEB8BC;\par
\tab background:none repeat scroll 0 0 #DFF4FF;\par
\tab width: 100%;\par
\tab text-align: center;\par
\tab line-height: 20px;\tab\par
\tab cursor: pointer;\par
\tab -moz-border-radius: 5px;\par
\tab -webkit-border-radius: 5px;\par
\tab -khtml-border-radius: 5px;\par
\}\par
\par
#pendingResults:hover \{\par
\tab text-decoration: underline;\tab\tab\par
\}\par
\par
.proxyExcludeTag\par
\{\par
  display: block;\par
  min-width: 15em;\par
  \}\par
img.deleteTag,img.deleteProxyExcludeTag \{\par
\tab width: 8px;\par
\tab height: 8px;\par
\tab margin-left: 3px;\par
\tab cursor: pointer;\par
\}\par
\par
img.deleteProxyExcludeTag \par
\{\par
  float:right;\par
  vertical-align: center;\par
  margin: 3px;\par
\}\par
\par
td.rb \{\par
\tab text-align: right;\par
    vertical-align: bottom;\par
\}\par
\par
#loadingIndicatorMessage \{\par
\tab display: inline-block;\par
\tab margin-left: 10px;\par
\tab vertical-align: super;\par
\tab color:#407BB3;\par
\tab font-size:14px;\par
\}\par
\par
#loadingIndicator \{\par
\tab border:2px solid #ccc;\par
\tab margin: 10px;\par
\tab padding: 10px;\par
\tab width: 100px;\par
\tab background-color: white;\par
\tab\par
\tab\par
\tab\par
\tab -moz-border-radius: 20px;\par
    -webkit-border-radius:20px;\par
    -khtml-border-radius:20px;\par
    -moz-box-shadow: 0 1px 5px #333;\par
    -webkit-box-shadow: 0 1px 5px #333;\par
\}\par
\par
#loadingIndicator IMG \{\par
\tab height: 30px;\par
\tab width: 30px;\par
\tab background: transparent;\par
\}\par
\par
.signinOverlay, #loadingOverlay \{\par
    position:fixed;\par
    top:0px;\par
    bottom:0px;\par
    left:0px;\par
    right:0px;\par
    z-index:100;\par
\}\par
\par
.signinOverlay \{\par
\tab background: url(../img/overlay.png) repeat top left;\par
\}\par
\par
.signinBox\{\par
    position:fixed;\par
    top:-325px;\par
    left:30%;\par
    right:30%;\par
    background-color:#fff;\par
    color:#7F7F7F;\par
    padding:20px;\par
    border:2px solid #ccc;\par
    -moz-border-radius: 20px;\par
    -webkit-border-radius:20px;\par
    -khtml-border-radius:20px;\par
    -moz-box-shadow: 0 1px 5px #333;\par
    -webkit-box-shadow: 0 1px 5px #333;\par
    z-index:101;\par
\}\par
\par
.signinBox h1\par
\{\par
    border-bottom: 1px dashed #7F7F7F;\par
    margin:-20px -20px 0px -20px;\par
    padding:10px;\par
    background-color:#eef3f8;\par
    color:#407BB3;\par
    -moz-border-radius:20px 20px 0px 0px;\par
    -webkit-border-top-left-radius: 20px;\par
    -webkit-border-top-right-radius: 20px;\par
    -khtml-border-top-left-radius: 20px;\par
    -khtml-border-top-right-radius: 20px;\par
\}\par
\par
.signinBox input[type="text"], .signinBox input[type="password"] \{\par
\tab width: 155px;\par
\}\par
  \par
/*\par
admin settings\par
*/  \par
  .adminSettings input[type="text"]\par
\{ \par
  margin: 1px;\par
  width: 300px;\par
 \}\par
 \par
  .adminSettings input[type="password"]\par
\{ \par
  margin: 1px;\par
  width: 300px;\par
 \}\par
 \par
   .adminSettings input[type="checkbox"]\par
\{ \par
  margin: 1px; \par
 \}\par
 \par
.inputRow \{\par
\tab clear: both;\par
\tab height: 28px;\par
\}\par
\par
.inputRow label \{\par
\tab display: inline-block;\par
\tab float: left;\par
\tab min-width: 16em;\par
\tab text-align: left-center;\par
\tab margin: 1px;\par
\tab vertical-align: middle;\par
\}\par
\par
.inputRow input[type="text"] \{\par
\tab margin: 1px;\par
\}\par
 \par
 .adminSettings label \par
\{\par
  display: inline-block;\par
  float: left;\par
  min-width: 16em;\par
  height: 28px;\par
  text-align: left-center;\par
  margin: 1px;\par
\}\par
\par
  .adminSettings span\par
\{\par
\tab float: left;\par
\tab width: 350px;\par
\tab word-wrap: break-word; \par
\}\par
\par
#purgeSettings label \{\par
\tab min-width: 24em;\par
\}\par
\par
#reportingUserSettings label \{\par
\tab min-width: 14em;\par
\}\par
\par
#purgeSettings input[type="text"] \{\par
\tab width: 60px;\par
\}\par
\par
.server_status \{\par
\tab margin: 20px 0;\par
\tab float: left;\par
\}\par
\par
ul \{\par
\tab margin: 0px;\par
\tab padding-left: 14px;\par
\}\par
\par
.server_status label\{\par
\tab display:block;\par
\tab width:100%;\tab\par
\}\par
\par
.server_status ul \{\par
\tab margin-top: 5px;\par
\tab width: 150px;\par
\tab float:left;\par
\}\par
\par
.server_status ul li \{\par
\tab height: 20px;\par
\}\par
\par
.server_status ul li label \{\par
\tab display: inline-block;\par
\tab width: 65px;\par
\}\par
\par
ul.notification_status li label\{\par
\tab width:45px;\par
\}\par
\par
.system_stats\{\par
\tab clear:both;\par
\tab margin-top:20px;\tab\par
\}\par
\par
.drawer_title \{\par
\tab clear: both;\par
\tab margin-top: 10px;\par
\}\par
\par
.drawer_title IMG \{\par
\tab width: 10px;\par
\tab height: 10px;\par
\tab cursor: pointer;\par
\}\par
\par
div.drawer \{\par
\tab float: left;\par
\tab margin: 10px 0 5px 14px;\par
\tab padding-bottom: 10px;\par
\tab width: 550px;\par
\tab border-bottom: thin solid #407BB3;\par
\}\par
\par
.heading \par
\{\par
\tab color:#407BB3;\par
\tab font-size:14px;\par
\}\par
\par
.heading:hover \par
\{\par
\tab color:#407BB3;\par
\tab text-decoration: underline;\par
\tab cursor: pointer;\par
\}\par
\par
.campaignResultsSettingsLayer\par
\{\par
\tab float: left;\par
\tab margin-left: 5px;\par
\tab width: 99%;\par
\}\par
\par
.campaignResultsBoxes\par
\{\par
\tab width:400px;\par
\tab height:110px;\par
\}\par
\par
.campaignResultsSettingsHeader \{\par
\tab font-size:14px;\par
\tab font-weight:bold;\par
\tab display: block;\par
\tab margin-top:15px;\par
    margin-bottom:5px;\tab\par
\}\par
\par
.firstHeader \{\par
\tab margin-top: 0px;\par
\}\par
\par
.campaignResultsCheckBox \{\par
\tab margin: 0px;\par
\tab margin-bottom:4px;\par
\tab\par
\}\par
\par
.example \{\par
\tab color:#888888;\par
\tab font-size:10px;\par
\tab vertical-align: middle;\par
\}\par
\par
#sampleCodeDrawerContents \{\par
\tab border: 1px solid #7F7F7F;\par
\tab border: thin solid #407BB3;\par
\tab margin-top: 10px;\par
\tab margin-left: 15px;\par
\tab margin-right: 15px;\par
\}\par
\par
#sampleCodeDisplayHeader \{\par
\tab background-color: #eef3f8;\par
\tab font-size: 14px;\par
\tab padding: 3px;\par
\}\par
\par
#sampleCodeDisplayContent \{\par
\tab padding: 3px;\par
\}\par
\par
ul.topnav \{\par
\tab list-style: none;\par
\tab padding: 0;\par
\tab margin: 0;\par
\tab float: left;\par
\tab z-index: 10;\par
\}\par
ul.topnav li \{\par
\tab cursor: pointer;\par
\tab float: left;\par
\tab margin: 0;\par
\tab padding: 1px 5px 1px 5px;\par
\tab position: relative; /*--Declare X and Y axis base for sub navigation--*/\par
\tab font-size: 1.2em;\par
\tab max-width:450px;\par
\tab border: 1px solid #EEF3F8;\par
\tab -webkit-border-radius: 5px;\par
\tab -moz-border-radius: 5px;\par
\tab border-radius: 5px;\par
\}\par
ul.topnav li:hover\{\par
\tab border: 1px solid #407BB3;\par
\}\par
ul.topnav li span.menuTitle \{\par
\tab float: left;\par
\tab overflow-x: hidden;\par
\tab white-space: nowrap;\par
\tab max-width: 430px;\par
\}\par
ul.topnav li span.arrow \{ /*--Drop down trigger styles--*/\par
\tab width: 12px;\par
\tab height: 24px;\par
\tab float: right;\par
\tab background: url(../img/drawerTriangleOpen.png) no-repeat center center;\par
\}\par
ul.topnav li ul.subnav \{\par
\tab font-size: 14px;\par
\tab list-style: none;\par
\tab position: absolute;\par
\tab left: 0; top: 28px;\par
\tab background: #fff;\par
\tab margin: 0; padding: 0;\par
\tab display: none;\par
\tab float: left;\par
\tab border: 1px solid #407BB3;\par
\tab max-height: 500px;\par
\tab max-width: 650px;\par
\tab -webkit-border-radius: 5px;\par
\tab -webkit-border-top-left-radius: 0;\par
\tab -moz-border-radius: 5px;\par
\tab -moz-border-radius-topleft: 0;\par
\tab border-radius: 5px;\par
\tab border-top-left-radius: 0;\par
\tab overflow-x: hidden;\par
\tab overflow-y: auto;\par
\tab text-overflow: ellipsis;\par
\tab white-space: nowrap;\par
\}\par
ul.topnav li ul.subnav li:first-child\{\par
\tab border: none;\par
\}\par
ul.topnav li ul.subnav li\{\par
\tab margin: 0; padding: 0;\par
\tab border: none;\par
\tab border-radius: 0;\par
\tab -webkit-border-radius: 0;\par
\tab -moz-border-radius: 0;\par
\tab border-top: 1px solid #407BB3;\par
\tab clear: both;\par
\tab cursor: pointer;\par
\tab width:100%;\par
\tab max-width:650px;\par
\}\par
ul.topnav li ul.subnav li:hover\{\par
\tab background: #EEF3F8;\par
\}\par
html ul.topnav li ul.subnav li span \{\par
\tab float: left;\par
\tab padding-left: 5px;\par
\tab background: none;\par
\}\par
\par
\par
.notificationRow \{\par
\tab clear: both;\par
\tab height: 28px;\par
\}\par
\par
.notificationRow label \{\par
\tab display: inline-block;\par
\tab float: left;\par
\tab min-width: 10em;\par
\tab text-align: left-center;\par
\tab margin: 1px;\par
\tab vertical-align: middle;\par
\tab margin-left: 1em; \par
\}\par
\par
.notificationRow input[type="text"] \{\par
\tab margin: 1px;\par
\tab width: 50%;\par
\}\par
\par
.notificationRow select \{\par
\tab margin: 1px;\par
\tab width: 51%;\par
\}\par
\par
.notificationRow textarea \{\par
\tab margin: 1px;\par
\tab width: 60%;\par
\}\par
\par
.addressList\par
\{ \par
  margin-left: 10em;\par
  overflow:auto;\par
  width: 52%;\par
 \}\par
 \par
 /* DataTable styles */\par
\par
table.display \{\par
\tab clear: both;\par
\tab margin-top: 5px;\par
\tab margin-bottom: 5px;\par
\tab width: 100%;\par
\tab border-bottom: 1px solid #CCCCCC;\par
\tab border-top: 1px solid #CCCCCC;\par
\}\par
\par
table.display thead th \{\par
\tab padding: 3px 5px 3px 5px;\par
\tab background-color: white; /* #D9E5F0; - TODO - change to this color once the sorting arrows have a new color */\par
\tab font-weight: bold;\par
\tab border-bottom: 1px solid #CCCCCC;\par
\tab border-top-style: none;\par
\}\par
\par
table.display td \{\par
\tab padding: 4px;\par
\}\par
\par
table.display td.center \{\par
\tab text-align: center;\par
\}\par
\par
tr.even \{\par
\tab background-color: #EFF3F6;\par
\}\par
\par
.sorting, .sorting_asc, .sorting_desc \{ \par
\tab cursor: pointer;\par
\}\par
\par
.sorting_asc \{\par
\tab background: url('../img/sort_asc.png') no-repeat center right;\par
\}\par
\par
.sorting_desc \{\par
\tab background: url('../img/sort_desc.png') no-repeat center right;\par
\}\par
\par
.sorting \{\par
\tab background: url('../img/sort_both.png') no-repeat center right;\par
\}\par
\par
.dataTables_filter \{\par
\tab float: left;\par
\tab font-size: 10px;\par
\}\par
\par
.dataTables_info \{\par
\tab float: right;\par
\tab font-size: 10px;\par
\tab line-height: 22px;\par
\}\par
\par
\par
\par
.profileName\par
\{\par
    display: inline-block;\par
    font-weight: bold;\par
    font-size: 14px;\par
    height: 22px;\par
    line-height: 16px;\par
    padding-top: 0px;\par
    padding-bottom: 5px;\par
    text-align: left;\par
    vertical-align: middle;\par
    width: 100%;\par
\}\par
\par
.profilePicture\par
\{\par
    float: left;\par
    padding-bottom: 2px;\par
\}\par
\par
.profile\par
\{\par
    margin-left: 58px;\par
\}\par
\par
.profileText\par
\{\par
    display: inline-block;\par
    font-size: 12px;\par
    line-height: 16px;\par
    text-align: left;\par
    vertical-align: middle;\par
    padding-bottom: 4px;\par
    width: 100%;\par
\}\par
\par
.profileUrl\par
\{\par
    display: inline-block;\par
    font-size: 12px;\par
    line-height: 16px;\par
    text-align: left;\par
    vertical-align: middle;\par
    padding-bottom: 4px;\par
    width: 100%;\par
\}\par
\par
.profileUrl:hover\par
\{\par
    display: inline-block;\par
    font-size: 12px;\par
    line-height: 16px;\par
    text-align: left;\par
    vertical-align: middle;\par
    padding-bottom: 4px;\par
    width: 100%;\par
    cursor: pointer;\par
    text-decoration: underline;\par
\}\par
\par
.conversation\par
\{\par
    float: left;\par
    height: 350px;\par
    overflow: auto;\par
    padding-top: 10px;\par
    width: 100%;\par
\}\par
\par
.author\par
\{\par
    border-top: thin outset #407BB3;\par
    display: inline-block;\par
    font-weight: bold;\par
    font-size: 14px;\par
    height: 22px;\par
    line-height: 16px;\par
    padding-top: 1px;\par
    text-align: left;\par
    vertical-align: middle;\par
    width: 100%;\par
\}\par
\par
.repliedToTweet\par
\{\par
    bottom: 0;\par
    padding-left: 5px;\par
    padding-right: 5px;\par
    width: 480px;\par
\}\par
\par
.retweetedTweet\par
\{\par
    padding-left: 5px;\par
    padding-right: 5px;\par
    width: 490px;\par
    background: white;\par
\}\par
\par
.authorSmall\par
\{\par
    display: inline-block;\par
    font-weight: bold;\par
    font-size: 12px;\par
    height: 20px;\par
    line-height: 14px;\par
    padding-top: 1px;\par
    text-align: left;\par
    vertical-align: bottom;\par
    width: 100%;\par
\}\par
\par
.descriptionSmall\par
\{\par
    display: inline-block;\par
    font-weight: normal;\par
    font-size: 12px;\par
    line-height: 14px;\par
    padding-top: 1px;\par
    padding-bottom: 5px;\par
    text-align: left;\par
    vertical-align: bottom;\par
    width: 100%;\par
\}\par
\par
.draggableDialog\par
\{\par
    visibility: hidden;\par
    background-color: #407BB3;\par
    outline-color:  #407BB3;\par
    outline-style: solid;\par
    outline-width: thick;\par
    position: absolute;\par
    top: 50px;\par
    left: 10px;\par
    width: auto;\par
    height: auto;\par
\}\par
\par
.draggableDialogHeader\par
\{\par
    position:absolute;\par
    top:0px;\par
    left:0px;\par
    width:100%;\par
    height:25px;\par
    cursor:move;\par
    background-color:#EEF3F8;\par
    font-weight:bold;\par
\}\par
\par
.innerDialog\par
\{\par
    position:relative;\par
    margin:25px 0px 0px 0px;\par
    outline-color:#EEF3F8;\par
    outline-style:thick;\par
    background-color:white;\par
    width:100%;\par
    height:auto;\par
\}\par
\par
.closeDialog\par
\{\par
    cursor:pointer;\par
    position:absolute;\par
    top:2px;\par
    right:5px;\par
    font:bold 16px/18px Tahoma,sans-serif;\par
    color:#000000;\par
\}\par
\par
.tweetArea\par
\{\par
    font-family:Arial;\par
    font-size:12px;\par
    line-height:16px;\par
    padding-left:8px;\par
    padding-top:2px;\par
    vertical-align:middle;\par
    margin:5px 5px 5px 5px;\par
    width:480px;\par
    height:100px;\par
\}\par
\par
.dialogButtons\par
\{\par
    display: block;\par
    padding: 10px 0 10px 0;\par
    text-align: right;\par
    width: 480px;\par
\}\par
\par
.sendButton\par
\{\par
    right:5px;\par
\}\par
\par
.tweetButton\par
\{\par
    padding-right: 5px;\par
    padding-left: 5px;    \par
\}\par
\par
.countDown\par
\{\par
    text-align: right;\par
    padding-right: 5px;\par
    padding-left: 5px;\par
\}\par
\par
.actionGroup\par
\{\par
    padding-top:8px;\par
    padding-bottom:8px;\par
\}\par
\par
.replyAction\par
\{\par
    cursor:pointer;\par
    padding-left:4px;\par
    padding-right:4px;\par
    color:#407BB3;\par
\}\par
\par
.replyAction:hover\par
\{\par
    cursor:pointer;\par
    padding-left:4px;\par
    padding-right:4px;\par
    color:#407BB3;\par
    text-decoration:underline;\par
\}\par
\par
.progressLayer\par
\{\par
    position: absolute;\par
    top: 0;\par
    left: 0;\par
    opacity: 0.5;\par
    visibility: hidden;\par
    background-color: #EEF3F8;\par
    z-axis: 1;\par
\}\par
\par
.progressMessage\par
\{\par
    position: absolute;\par
    background-color: white;\par
    border-style: solid;\par
    border-width: medium;\par
    border-radius: 5px;\par
    -moz-border-radius: 5px;\par
    z-axis: 2;\par
    opacity: 1.0;\par
\}\par
\par
.progressSpan\par
\{\par
    font-size: 18px;\par
    font-weight: bold;\par
    padding: 5px 5px 5px 5px;\par
\}\par
\par
</style>\par
\par
<script type="text/javascript">\par
\par
\par
//\par
// The following code manages the dialog used to reply, retweet, and message\par
//\par
\par
/**\par
 * Keep track of the currently selected dialog\par
 */\par
var currentDialog = null ;\par
\par
/**\par
 * Class used to store information about a given dialog\par
 */\par
function DraggableDialog(grabbableClassName, dialogId)\par
\{\par
    this.grabbableClassName = grabbableClassName ;\par
    this.dialog = document.getElementById(dialogId) ;\par
\par
    this.offsetX = 0 ;\par
    this.offsetY = 0 ;\par
    this.dragging = false ;\par
\}\par
\par
/**\par
 * Set the currently displayed dialog\par
 */\par
function setDraggableDialog(grabbableClassName, dialogId)\par
\{\par
    if ( currentDialog != null )\par
    \{\par
        return ;\par
    \}\par
    \par
    currentDialog = new DraggableDialog(grabbableClassName, dialogId) ;\par
\par
    document.onmousedown = onMouseDown ;\par
    document.onmouseup   = onMouseUp ;\par
    document.onmousemove = onMouseMove ;\par
\}\par
\par
/**\par
 * Handle mouse down events.This consists of determining whether or not the\par
 * grabbable part of the dialog was clicked.\par
 */\par
function onMouseDown(event)\par
\{\par
    if ( currentDialog == null )\par
    \{\par
        return ;\par
    \}\par
\par
    if ( (event == null) || (event == undefined) )\par
    \{\par
        event = window.event ;\par
    \}\par
\par
    var target = event.target || event.srcElement ;\par
        \par
    if ( target.className == currentDialog.grabbableClassName )\par
    \{\par
        currentDialog.offsetX = event.clientX - currentDialog.dialog.offsetLeft ;\par
        currentDialog.offsetY = event.clientY - currentDialog.dialog.offsetTop ;\par
\par
        currentDialog.dragging = true ;\par
    \}\par
\}\par
\par
/**\par
 * Handle mouse up. Stop dragging the dialog.\par
 */\par
function onMouseUp(event)\par
\{\par
    if ( currentDialog == null )\par
    \{\par
        return ;\par
    \}\par
\par
    currentDialog.dragging = false ;\par
\}\par
\par
/**\par
 * Redraw the dialog if th user is dragging it\par
 */\par
function onMouseMove(event)\par
\{\par
    if ( currentDialog == null )\par
    \{\par
        return ;\par
    \}\par
\par
    if ( (event == null) || (event == undefined) )\par
    \{\par
        event = window.event ;\par
    \}\par
    \par
    if ( currentDialog.dragging )\par
    \{\par
        currentDialog.dialog.style.left = (event.clientX - currentDialog.offsetX) + "px" ;\par
        currentDialog.dialog.style.top  = (event.clientY - currentDialog.offsetY) + "px" ;\par
    \}\par
\}\par
\par
/**\par
 * Open/display the currently selected dialog\par
 */\par
function openDialog()\par
\{\par
    if ( currentDialog == null )\par
    \{\par
        return ;\par
    \}\par
\par
    currentDialog.dialog.style.visibility = "visible" ;\par
\}\par
\par
/**\par
 * Close/hide the currently selected dialog\par
 */\par
function closeDialog()\par
\{\par
    if ( currentDialog == null )\par
    \{\par
        return ;\par
    \}\par
\par
    currentDialog.dialog.style.visibility = "hidden" ;\par
    \par
    currentDialog = null ;\par
\}\par
   \par
\par
/**\par
 * Parameter name of the social contact's reference URL.  The value of\par
 * this parameter is used to derive the other REST paths used in the\par
 * reply template.\par
 */\par
var SC_REF_URL_PARAM = "scRefUrl" ;\par
\par
/**\par
 * Parameter that stores the origin of the campaign results gadget.\par
 */\par
var ORIGIN_PARAM = "origin" ;\par
\par
/**\par
 * CCP Feed API path\par
 */\par
var CCP_FEED_REST_PATH    = "/ccp-webapp/ccp/feed" ;\par
\par
/**\par
 * CCP Twitter status update API path \par
 */\par
var STATUS_MESSAGE_PATH   = "/ccp-webapp/ccp/reply/twitter/statuses/update" ;\par
\par
/**\par
 * CCP Twitter retweet API path \par
 */\par
var STATUS_RETWEET_PATH   = "/ccp-webapp/ccp/reply/twitter/statuses/retweet" ;\par
\par
/**\par
 * CCP Twitter direct message API path\par
 */\par
var DIRECT_MESSAGE_PATH   = "/ccp-webapp/ccp/reply/twitter/direct_messages/new" ;\par
\par
/**\par
 * CCP Twitter friendships/exists API path\par
 */\par
var FRIENDSHIPS_EXISTS_PATH = "/ccp-webapp/ccp/reply/twitter/friendships/exists" ;\par
\par
/**\par
 * CCP Twitter follow API path\par
 */\par
var FOLLOW_PATH = "/ccp-webapp/ccp/reply/twitter/follow" ;\par
\par
/**\par
 * CCP Twitter unfollow API path\par
 */\par
var UNFOLLOW_PATH = "/ccp-webapp/ccp/reply/twitter/unfollow" ;\par
\par
/**\par
 * CCP Twitter users show API path\par
 */\par
var USERS_SHOW_PATH = "/ccp-webapp/ccp/reply/twitter/users/show" ;\par
\par
/**\par
 * CCP API to retrieve a conversation ending with the given contact\par
 */\par
var CONVERSATION_PATH = "/ccp-webapp/ccp/conversation" ;\par
/**\par
 * Social contact handled state\par
 */\par
var SC_STATUS_HANDLED = "handled" ;\par
\tab\par
/**\par
 * Social contact reserved state\par
 */\par
var SC_STATUS_RESERVED = "reserved" ;\par
\par
var TWITTER_PROGRESS_SUCCEEDED\tab  = "SUCCEEDED";\par
var TWITTER_PROGRESS_FAILED\tab\tab  = "FAILED";\par
var TWITTER_PROGRESS_IN_PROGRESS = "IN-PROGRESS";\par
\par
var PROGRESS_TAG          = "progress" ;\par
var HTTP_RESPONSE_MSG_TAG = "httpResponseMessage" ;\par
var RATE_LIMITED_TAG      = "rateLimited" ;\par
\par
//\par
// Utility Functions\par
//\par
\par
/**\par
 * Determine if the given string is undefined, null, or is empty\par
 */\par
function isEmptyString(string)\par
\{\par
    if ( (string == undefined) || (string == null) || (string == "") )\par
    \{\par
        return true ;\par
    \}\par
    \par
    return false ;\par
\}\par
\par
/**\par
 * Found the parameter with the given name in the URL used to retrieve this\par
 * page.\par
 */\par
function getRequestParameterValue(paramName, url)\par
\{\par
\tab paramName = paramName.replace(/[\\[]/,"\\\\\\[").replace(/[\\]]/,"\\\\\\]") ;\par
\tab var regexS = "[\\\\?&]" + paramName + "=([^&#]*)" ;\par
\tab var regex = new RegExp(regexS) ;\par
\tab var results = regex.exec(url) ;\par
\tab if( results == null )\par
\tab\{\par
\tab  \tab return "" ;\par
\tab\}\par
\par
\tab return results[1] ;\par
\}\par
\par
/**\par
 * Retrieve the node with the given name from the xml contained in the xml\par
 * parameter\par
 */\par
function getElementValue(xml, nodeName)\par
\{\par
    if ( xml == undefined )\par
    \{\par
        log("xml is undefined for " + nodeName) ;\par
    \}\par
    \par
\tab var element = xml.getElementsByTagName(nodeName) ;\par
\tab if ( (element == null) ||\par
\tab      (element[0] == null) ||\par
\tab      (element[0].childNodes[0] == null) )\par
\tab\{\par
\tab\tab return "" ;\par
\tab\}\par
\tab\par
\tab return element[0].childNodes[0].nodeValue ;\par
\}\par
\par
/**\par
 * Log to Firebug if it is present\par
 */\par
function log(msg)\par
\{\par
\tab if( typeof console === "undefined" )\par
\tab\{\par
\tab     return ;\par
\tab\}\par
\tab\par
\tab console.log(msg) ;\par
\}\par
\par
//\par
// Twitter Message class definition\par
//\par
\par
/**\par
 * Class used to manage calls to the Twitter reply API. This class will make the\par
 * REST request and then poll until the operation completes.\par
 */\par
function TwitterMessage(ccpSession, url, method, callback, postData)\par
\{\par
\tab this.ccpSession = ccpSession ;\par
\tab\par
\tab this.method   = method ;\par
\tab this.url      = url ;\par
\tab\par
\tab this.callback = callback ;\par
\tab this.postData = postData ;\par
\tab\par
\tab this.intervalId = null ;\par
\tab\par
\tab this.statusUrl = null ;\par
\}\par
\par
/**\par
 * Stop polling for progress\par
 */\par
TwitterMessage.prototype.stopPolling = function()\par
\{\par
\tab if ( this.intervalId == null )\par
\tab\{\par
\tab\tab return ;\par
\tab\}\par
\par
\tab clearInterval(this.intervalId) ;\par
\tab\par
\tab log("interval[" + this.intervalId + "] clear") ;\par
\par
\tab this.intervalId = null ;\par
\tab this.statusUrl = null ;\par
\}\par
\par
/**\par
 * Check the progress of the operation\par
 */\par
TwitterMessage.prototype.checkProgress = function()\par
\{\par
\tab var self = this ;\par
\tab\par
\tab var progressCallback = function(obj)\par
\tab\{\par
\tab\tab if ( obj.rc != 200 )\par
\tab\tab\{\par
\tab\tab\tab self.stopPolling() ;\par
\tab\tab\tab self.callback(obj, self) ;\par
\tab\tab\tab\par
\tab\tab\tab return ;\par
\tab\tab\}\par
\par
\tab\tab var progress = getElementValue(obj.data, PROGRESS_TAG) ;\par
\tab\tab if ( (progress == TWITTER_PROGRESS_SUCCEEDED) ||\par
\tab\tab\tab  (progress == TWITTER_PROGRESS_FAILED) )\par
\tab\tab\{\par
\tab\tab\tab self.stopPolling() ;\par
\tab\tab\tab self.callback(obj, self) ;\par
\tab\tab\}\par
\tab\tab\par
\tab\tab // If progress == IN_PROGRESS, let the interval continue to poll\par
\tab\tab // for status.\par
\tab\tab //\par
\tab\}\par
\tab\par
\tab this.ccpSession.makeRequest(this.statusUrl, gadgets.io.MethodType.GET, progressCallback) ;\par
\}\par
\par
/**\par
 * Send the initial request\par
 */\par
TwitterMessage.prototype.send = function()\par
\{\par
\tab var self = this ;\par
\tab\par
\tab var initialCallback = function(obj)\par
\tab\{\par
\tab\tab if ( obj.rc != 202 )\par
\tab\tab\{\par
\tab\tab\tab self.callback(obj, self) ;\par
\tab\tab\tab\par
\tab\tab\tab return ;\par
\tab\tab\}\par
\tab\tab\par
\tab\tab self.statusUrl = obj.headers.location[0] ;\par
\tab\tab\par
\tab\tab function progressInterval()\par
\tab\tab\{\par
\tab\tab\tab self.checkProgress() ;\par
\tab\tab\}\par
\tab\tab self.intervalId = setInterval(progressInterval, 1000) ;\par
\tab\tab log("interval[" + self.intervalId + "] set") ;\par
\tab\}\par
\tab this.ccpSession.makeRequest(self.url, self.method, initialCallback, self.postData) ;\par
\}\par
\par
\par
//\par
// CcpSession class definition\par
//\par
\par
/**\par
 * The CcpSession class allows applications to interact with CCP as follows:\par
 *   - get the details of the social contact\par
 *   - change the state of the social contact\par
 *   - get the list of Twitter accounts available on CCP.  These accounts can\par
 *     be used to send Twitter messages\par
 *   - send Twitter status updates and direct messages\par
 * \par
 * The href parameter is the URL of the reply template.  It is expected to\par
 * have an scRefUrl parameter in it.  This parameter is used to find the\par
 * protocol, port, and server to use to communicate with CCP.  \par
 */\par
function CcpSession(href)\par
\{\par
\tab this.restSocialContact = unescape(getRequestParameterValue(SC_REF_URL_PARAM, unescape(href))) ;\par
\tab\par
\tab var ccpProtocol = "" ;\par
\tab var ccpHost = "" ;\par
\tab var ccpPort = "" ;\par
\tab\par
\tab // The following regex parses the protocol, host, and port from the social\par
\tab // contact's refUrl.  This gives the page a path back to CCP's REST APIs.\par
\tab //\par
\tab e = /([^:]+):\\/\\/([^:/]+):*([0-9]*)/ ;\par
\tab var array = this.restSocialContact.match(e) ;\par
\tab if ( array != null )\par
\tab\{\par
\tab\tab ccpProtocol = array[1] ;\par
\tab\tab ccpHost = array[2] ;\par
\tab\tab ccpPort = array[3] ;\par
\tab\}\par
\tab\par
\tab var ccpBasePath = ccpProtocol + "://" + ccpHost + (ccpPort == "" ? "" : ":" + ccpPort) ;\par
\tab\par
\tab this.restGetFeedList       = ccpBasePath + CCP_FEED_REST_PATH ;\tab\par
\tab this.restSendStatusMessage = ccpBasePath + STATUS_MESSAGE_PATH ;\par
    this.restRetweetMessage    = ccpBasePath + STATUS_RETWEET_PATH ;\par
\tab this.restSendDirectMessage = ccpBasePath + DIRECT_MESSAGE_PATH ;\par
\tab this.restFriendshipsExists = ccpBasePath + FRIENDSHIPS_EXISTS_PATH ;\par
\tab this.restFollow            = ccpBasePath + FOLLOW_PATH ;\par
    this.restUnfollow          = ccpBasePath + UNFOLLOW_PATH ;\par
\tab this.restUsersShow         = ccpBasePath + USERS_SHOW_PATH ;\par
\tab this.restGetConversation   = ccpBasePath + CONVERSATION_PATH ;\par
\tab\par
\tab this.prefs = new gadgets.Prefs() ;\par
\tab\par
\tab // Location of the campaign-results gadget.  This attribute is necessary\par
\tab // to post messages to the campaign results gadget.\par
\tab //\par
\tab this.origin = this.prefs.getString("origin") ;\par
\tab\par
\tab // Authorization string used to make REST requests to CCP.\par
\tab //\par
\tab this.authString = this.prefs.getString("CCPAuthString") ;\par
\par
\tab // Message used for following and friendship requests\par
\tab this.currentFollow = null ;\par
\tab\par
\tab // Message used for direct messages and tweets\par
\tab this.currentMessage = null ;\par
\}\par
\par
/**\par
 * Get the social contact's details.\par
 */\par
CcpSession.prototype.getSocialContact = function(callback)\par
\{\par
\tab this.makeRequest(this.restSocialContact, gadgets.io.MethodType.GET, callback) ;\par
\}\par
\par
/**\par
 * Get the list of feeds configured on CCP.\par
 */\par
CcpSession.prototype.getAllCcpFeeds = function(callback)\par
\{\par
\tab this.makeRequest(this.restGetFeedList, gadgets.io.MethodType.GET, callback) ;\par
\}\par
\par
/**\par
 * Manage handling of messages to Twitter via CCP.  This method allows one\par
 * follow-related message at a time.\par
 */\par
CcpSession.prototype.processFollow = function(url, method, callback, postData)\par
\{\par
\tab if ( this.currentFollow != null )\par
\tab\{\par
\tab\tab log("currentFollow: " + this.currentFollow.url + " is already set") ;\par
\tab\tab return ;\par
\tab\}\par
\tab\par
\tab var self = this ;\par
\tab var wrapCallback = function(obj, message)\par
\tab\{\par
\tab\tab log("currentFollow: " + self.currentFollow.url + " cleared") ;\par
\tab\tab self.currentFollow = null ;\par
\tab\tab callback(obj) ;\par
\tab\}\par
\tab this.currentFollow = new TwitterMessage(this, url, method, wrapCallback, postData) ;\par
\tab log("currentFollow: " + self.currentFollow.url + " set") ;\par
\tab this.currentFollow.send() ;\par
\}\par
\par
/**\par
 * Manage handling of messages to Twitter via CCP.\par
 */\par
CcpSession.prototype.processMessage = function(url, method, callback, postData)\par
\{\par
\tab if ( this.currentMessage != null )\par
\tab\{\par
\tab\tab log("currentMessage: " + this.currentMessage.url + " is already set") ;\par
\tab\tab return ;\par
\tab\}\par
\tab\par
\tab var self = this ;\par
\tab var wrapCallback = function(obj, message)\par
\tab\{\par
\tab\tab log("currentMessage: " + self.currentMessage.url + " cleared") ;\par
\tab\tab self.currentMessage = null ;\par
\tab\tab callback(obj) ;\par
\tab\}\par
\tab this.currentMessage = new TwitterMessage(this, url, method, wrapCallback, postData) ;\par
\tab log("currentMessage: " + self.currentMessage.url + " set") ;\par
\tab this.currentMessage.send() ;\par
\}\par
\par
/**\par
 * Send a status message using the Twitter account with the given username.\par
 */\par
CcpSession.prototype.twitterStatusUpdate = function(username, message, callback)\par
\{\par
\tab var postData =\par
\tab\tab\tab "<Status>\\n" +\par
\tab\tab\tab "  <username>" + username + "</username>\\n" +\par
\tab\tab\tab "  <message>" + message + "</message>\\n" +\par
\tab\tab\tab "</Status>" ;\par
\par
\tab this.processMessage(this.restSendStatusMessage, gadgets.io.MethodType.POST, callback, postData) ;\par
\}\par
\par
/**\par
 * Send a status message using the Twitter account with the given username.\par
 */\par
CcpSession.prototype.twitterReply = function(username, message, statusId, callback)\par
\{\par
\tab var postData =\par
\tab\tab\tab "<Status>\\n" +\par
\tab\tab\tab "  <username>" + username + "</username>\\n" +\par
\tab\tab\tab "  <message>" + message + "</message>\\n" +\par
\tab\tab\tab "  <inReplyToStatusId>" + statusId + "</inReplyToStatusId>\\n" +\par
\tab\tab\tab "</Status>" ;\par
\par
\tab this.processMessage(this.restSendStatusMessage, gadgets.io.MethodType.POST, callback, postData) ;\par
\}\par
\par
/**\par
 * Send a direct message using the account specified by fromUsername to the user\par
 * specified in toUsername.\par
 */\par
CcpSession.prototype.twitterDirectMessage = function(fromUsername, toUsername, message, callback)\par
\{\par
\tab var postData =\par
\tab\tab "<DirectMessage>\\n" +\par
\tab\tab "  <fromUsername>" + fromUsername + "</fromUsername>\\n" +\par
\tab\tab "  <toUsername>" + toUsername + "</toUsername>\\n" +\par
\tab\tab "  <message>" + message + "</message>\\n" +\par
\tab\tab "</DirectMessage>" ;\par
\par
\tab this.processMessage(this.restSendDirectMessage, gadgets.io.MethodType.POST, callback, postData) ;\par
\}\par
\par
/**\par
 * Retweet the specified tweet.\par
 */\par
CcpSession.prototype.twitterRetweet = function(username, tweetId, callback)\par
\{\par
    var postData =\par
            "<Status>\\n" +\par
            "  <username>" + username + "</username>\\n" +\par
            "  <tweetId>" + tweetId + "</tweetId>\\n" +\par
            "</Status>" ;\par
\par
    this.processMessage(this.restRetweetMessage, gadgets.io.MethodType.POST, callback, postData) ;\par
\}\par
\par
CcpSession.prototype.twitterFollow = function(account_user, user_to_follow, callback)\par
\{\par
\tab var restUrl = this.restFollow + "?account_user=" + account_user + "&user_to_follow=" + user_to_follow ;\par
\tab this.processFollow(restUrl, gadgets.io.MethodType.POST, callback) ;\par
\}\par
\par
CcpSession.prototype.twitterUnfollow = function(account_user, user_to_follow, callback)\par
\{\par
    var restUrl = this.restUnfollow + "?account_user=" + account_user + "&user_to_unfollow=" + user_to_follow ;\par
    this.processFollow(restUrl, gadgets.io.MethodType.POST, callback) ;\par
\}\par
\par
/**\par
 * Determine if userA s following userB\par
 */\par
CcpSession.prototype.twitterFriendshipExists = function(oauthUsername, userA, userB, callback)\par
\{\par
\tab var restUrl = this.restFriendshipsExists + "?user_a=" + userA + "&user_b=" + userB ;\par
    if ( !isEmptyString(oauthUsername) )\par
    \{\par
        restUrl = restUrl + "&account_user=" + oauthUsername ;\par
    \}\par
    var followMessage = new TwitterMessage(this, restUrl, gadgets.io.MethodType.GET, callback) ;\par
    followMessage.send() ;\par
\}\par
\par
/**\par
 * Retrieve the user with the given screen name's profile\par
 */\par
CcpSession.prototype.twitterUsersShow = function(oauthUsername, screenName, callback)\par
\{\par
    var restUrl = this.restUsersShow + "?screenName=" + screenName ;\par
    if ( !isEmptyString(oauthUsername) )\par
    \{\par
        restUrl = restUrl + "&account_user=" + oauthUsername ;\par
    \}\par
    this.processMessage(restUrl, gadgets.io.MethodType.GET, callback) ;\par
\}\par
\par
/**\par
 * Retrieve the given contactId and its replies \par
 */\par
CcpSession.prototype.getConversation = function(contactId, callback)\par
\{\par
    var restUrl = this.restGetConversation + "/" + contactId ;\par
    this.makeRequest(restUrl, gadgets.io.MethodType.GET, callback) ;\par
\}\par
\par
/**\par
 * Submit an asynchronous request to a URL with the given HTTP method, \par
 * passing the given post data. The response is passed to the callback function.\par
 */\par
CcpSession.prototype.makeRequest = function(url, method, callback, postdata)\par
\{\par
    var params = \{\};\par
    params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.DOM;\par
    params[gadgets.io.RequestParameters.METHOD] = method;\par
    params[gadgets.io.RequestParameters.REFRESH_INTERVAL ] = 0;\par
\par
    switch (method)\par
    \{\par
    case gadgets.io.MethodType.DELETE:\par
        break;\par
    case gadgets.io.MethodType.POST:\par
    case gadgets.io.MethodType.PUT:\par
        params[gadgets.io.RequestParameters.POST_DATA] = postdata;\par
        params[gadgets.io.RequestParameters.HEADERS] = \{"Content-Type" : "application/xml;charset=UTF-8"\};        \par
        break;\par
    case gadgets.io.MethodType.GET:\par
        params[gadgets.io.RequestParameters.HEADERS] = \{"Cache-Control" : "no-cache"\};\par
        var timeparam = \{ time : (new Date()).getTime() \};\par
        if(url.indexOf("?") > 0)\par
        \tab url = url + "&" + gadgets.io.encodeValues(timeparam);\par
        else\par
        \tab url = url + "?" + gadgets.io.encodeValues(timeparam);     \par
        if (postdata != null)\par
            url = url + "&" + gadgets.io.encodeValues(postdata);\par
        break;\par
    \}\par
    \par
    var authHeader = "Basic " + this.authString ;\par
    if ( params[gadgets.io.RequestParameters.HEADERS] == null )\par
    \{\par
        params[gadgets.io.RequestParameters.HEADERS] = \{ "Authorization" :  authHeader \};\par
    \}\par
    else\par
    \{\par
        var headers = params[gadgets.io.RequestParameters.HEADERS];\par
        headers["Authorization"] = authHeader;\par
    \}\par
    \par
\tab gadgets.io.makeRequest(url, callback, params);\par
\}\par
\par
/**\par
 * Make multipe REST requests. Do not return until all requests have received\par
 * a response.\par
 */\par
CcpSession.prototype.makeMultipleGetRequests = function(urls, callback)\par
\{\par
    var responses = new Array(urls.length) ;\par
    \par
    var i = 0 ;\par
    for ( i = 0 ; i < urls.length ; i++ )\par
    \{\par
        var responseIndex = 0 ;\par
        var singleCallback = function singleCallback(response)\par
        \{\par
            responses[responseIndex] = response ;\par
            responseIndex++ ;\par
            \par
            var receivedAll = true ;\par
            for ( var j = 0 ; j < responses.length ; j++ )\par
            \{\par
                if ( responses[j] == undefined )\par
                \{\par
                    receivedAll = false ;\par
                    break ;\par
                \}\par
            \}\par
            \par
            if ( receivedAll )\par
            \{\par
                callback(responses) ;\par
            \}\par
        \}\par
        this.makeRequest(urls[i], gadgets.io.MethodType.GET, singleCallback) ;\par
    \}\par
\}\par
\par
/**\par
* Hide the reply and set the social contact's state to nextState.\par
*/\par
CcpSession.prototype.closeTemplate = function(nextState)\par
\{\par
\tab var message = "clearError" ;\par
\tab this.postMessage(message) ;\par
\tab\par
\tab message = "close:" + nextState ;\par
\tab this.postMessage(message) ;\par
\}\par
\par
/**\par
 * Set the heading for the reply template\par
 */\par
CcpSession.prototype.setHeading = function(heading)\par
\{\par
\tab var message = "heading:" + heading ;\par
\tab this.postMessage(message) ;\par
\}\par
\par
/**\par
 * Display the given error\par
 */\par
CcpSession.prototype.showError = function(text)\par
\{\par
\tab var message = "showError:" + text ;\par
\tab this.postMessage(message) ;\par
\}\par
\par
/**\par
* Clear errors using the CCP infrastructure\par
*/\par
CcpSession.prototype.clearError = function()\par
\{\par
\tab this.postMessage("clearError") ;\par
\}\par
\par
/**\par
 * Post a message to the parent window.\par
 */\par
CcpSession.prototype.postMessage = function(message)\par
\{\par
    log("Sending " + message) ;\par
\tab window.parent.window.parent.postMessage(message, this.origin) ;\par
\}\par
\tab\par
\par
//\par
// The following class stores information for a given social contact\par
//\par
\par
function SocialContact(ccpSession, contactXml)\par
\{\par
    this.ccpSession = ccpSession ;\par
    \par
    this.author      = getElementValue(contactXml, "author") ;\par
    this.title       = getElementValue(contactXml, "title") ;\par
    this.description = getElementValue(contactXml, "description") ;\par
    this.link        = getElementValue(contactXml, "link") ;\par
    this.refUrl      = getElementValue(contactXml, "refURL") ;\par
    \par
    this.isDM = false ;\par
    \par
    // Get the ID of the tweet or direct message\par
    //\par
    this.tweetId = null ;\par
    if ( this.link.indexOf("id=") >= 0 )\par
    \{\par
        this.isDM = true ;\par
        this.tweetId = this.link.substring(this.link.lastIndexOf("=") + 1) ;\par
    \}\par
    else\par
    \{\par
        this.tweetId = this.link.substring(this.link.lastIndexOf("/") + 1) ;\par
    \}\par
\}\par
   \par
\par
//\par
// The following class manages the author of the reserved contact's profile information\par
//\par
\par
/**\par
 * Class used to manage profile information\par
 */\par
function Profile(ccpSession, nameId, imageId, descriptionId, urlId, followerCountId, followingAgentId)\par
\{\par
    this.ccpSession = ccpSession ;\par
\par
    this.prefs = ccpSession.prefs ;\par
        \par
    this.name = document.getElementById(nameId) ;\par
    \par
    this.image = document.getElementById(imageId) ;\par
    \par
    this.description = document.getElementById(descriptionId) ;\par
    \par
    this.url = document.getElementById(urlId) ;\par
    \par
    this.followerCount = document.getElementById(followerCountId) ;\par
    \par
    this.followingAgent = document.getElementById(followingAgentId) ;\par
    \par
    this.followingAgentMap = [] ;\par
\}\par
\par
/**\par
 * Populate the reserved contact's author's Twitter profile information\par
 */\par
Profile.prototype.populate = function(author, selectedAccount, oauthAccount)\par
\{\par
    this.author = author ;\par
    \par
    if ( (this.author == null) || (this.author.length == 0) )\par
    \{\par
        return ;\par
    \}\par
    \par
    var profile = this ;\par
    \par
    var usersShowCallback = function(response)\par
    \{\par
        if ( handleRateLimit(response, oauthAccount) )\par
        \{\par
            return ;\par
        \}\par
            \par
        var error = getErrorDetails(response) ;\par
        if ( error != null )\par
        \{\par
            var errorMessage =\par
                profile.prefs.getMsg('twitter_reply_get_profile_failed') + " " + author + "<br>" +\par
                error ;\par
                \par
            showError(errorMessage) ;\par
            \par
            return ;\par
        \}\par
            \par
        var profileImageUrl = getElementValue(response.data, "profileImageUrl") ;\par
        if ( profileImageUrl != null )\par
        \{ \par
            profile.image.src = profileImageUrl ;\par
        \}\par
        \par
        var name = getElementValue(response.data, "name") ;\par
        if ( name != null )\par
        \{\par
            profile.name.innerHTML = name ;\par
        \}\par
        \par
        var description = getElementValue(response.data, "description") ;\par
        if ( isEmptyString(description) )\par
        \{\par
            description = "" ;\par
        \}\par
        profile.description.innerHTML = description ;\par
        \par
        var followerCount = getElementValue(response.data, "followersCount") ;\par
        if ( !isEmptyString(followerCount) )\par
        \{\par
            profile.followerCount.innerHTML = followerCount + " " + profile.prefs.getMsg('twitter_reply_followers') ;\par
        \}\par
        \par
        var screenName = getElementValue(response.data, "screenName") ;\par
        var url = getElementValue(response.data, "url") ;\par
        if ( isEmptyString(url) )\par
        \{\par
            url = "http://twitter.com/" + screenName ;\par
        \}\par
        profile.url.href = url ;\par
        profile.url.innerHTML = url ;\par
        \par
        profile.updateFollowing(selectedAccount) ;\par
    \}\par
    ccpSession.twitterUsersShow(oauthAccount, this.author, usersShowCallback) ;\par
\}\par
\par
/**\par
 * Update the UI based on whether or not the author of the reserved contact is\par
 * following the given agent\par
 */\par
Profile.prototype.updateFollowingUI = function(agent)\par
\{\par
    var following = this.followingAgentMap[agent] ;\par
    if ( (following == null) || (following == undefined) )\par
    \{\par
        following = false ;\par
    \}\par
    \par
    if ( following == true )\par
    \{\par
        this.followingAgent.innerHTML = this.prefs.getMsg('twitter_reply_following') + " " + agent ;\par
    \}\par
    else\par
    \{\par
        this.followingAgent.innerHTML = this.prefs.getMsg('twitter_reply_not_following') + " " + agent ;\par
    \}\par
\}\par
\par
/**\par
 * Update whether or not the author of the reserved contact is following the given\par
 * agent\par
 */\par
Profile.prototype.updateFollowing = function(agent)\par
\{\par
    if ( agent == null )\par
    \{\par
        this.followingAgent.innerHTML = "" ;\par
        \par
        return ;\par
    \}\par
    \par
    var state = this.followingAgentMap[agent] ;\par
    if ( (state != null) && (state != undefined) )\par
    \{\par
        this.updateFollowingUI(agent, state) ;\par
        \par
        return ;\par
    \}\par
    \par
    var profile = this ;\par
    var agentFriendshipsExistsCallback = function(response)\par
    \{            \par
        profile.followingAgentMap[agent] = null ;\par
\par
        if ( !handleRateLimit(response, agent) && (response.rc == 200) )\par
        \{\par
            var progress = getElementValue(response.data, PROGRESS_TAG) ;\par
            if ( progress != TWITTER_PROGRESS_FAILED )\par
            \{\par
                var friends = getElementValue(response.data, "friends") ;\par
                if ( friends != null )\par
                \{\par
                    if ( friends == "true" )\par
                    \{\par
                        profile.followingAgentMap[agent] = true ;\par
                    \}\par
                    else\par
                    \{\par
                        profile.followingAgentMap[agent] = false ;\par
                    \}\par
                \}   \par
            \}\par
        \}\par
            \par
        profile.updateFollowingUI(agent) ;\par
    \}\par
    ccpSession.twitterFriendshipExists(agent, author, agent, agentFriendshipsExistsCallback) ;\par
\}\par
   \par
\par
//\par
// The following class manages the conversation list in the reply template.\par
//\par
\par
var CONTACT_AUTHOR_PREFIX      = "contactAuthor_" ;\par
var CONTACT_LINK_PREFIX        = "contactLink_" ;\par
var CONTACT_DESCRIPTION_PREFIX = "contactDescription_" ;\par
var RETWEET_ACTION_PREFIX      = "retweetAction_" ;\par
var REPLY_ACTION_PREFIX        = "replyAction_" ;\par
var DM_ACTION_PREFIX           = "directMessage_" ;\par
\par
\par
/**\par
 * Class used to manage the conversation displayed on the reply template.\par
 */\par
function Conversation(ccpSession, conversationDivId)\par
\{\par
    this.contactId = null ;\par
   \par
    // Map the contact's reference URL to a SocialContact object.\par
    // \par
    this.urlToContactMap = [] ;\par
    \par
    this.contactList = [] ;\par
    \par
    this.conversationDiv = document.getElementById(conversationDivId) ;\par
    \par
    this.ccpSession = ccpSession ;\par
    \par
    this.prefs = ccpSession.prefs ;\par
\}\par
\par
/**\par
 * Create one of the actions placed at the bottom of each conversation entry\par
 */\par
Conversation.prototype.createAction = function(id, name)\par
\{\par
    var action = document.createElement("a") ;\par
    action.setAttribute("id", id) ;\par
    action.setAttribute("class", "replyAction") ;\par
    action.innerHTML = name ;\par
    \par
    return action ;\par
\}\par
\par
/**\par
 * Populate the conversation div\par
 */\par
Conversation.prototype.populate = function(contactId, account)\par
\{\par
    this.contactId = contactId ;\par
    \par
    var conversation = this ;\par
    \par
    var conversationCallback = function(response)\par
    \{\par
        if ( response.rc != 200 )\par
        \{\par
            showError(\par
                conversation.prefs.getMsg('twitter_reply_get_conversation_failed') + "<br>" +\par
                conversation.prefs.getMsg('twitter_reply_error_code') + " " + response.rc + "<br>" +\par
                conversation.prefs.getMsg('twitter_reply_error_message') + " " + response.text) ;\par
        \par
            return ;\par
        \}\par
        \par
        var contacts = response.data.getElementsByTagName("SocialContact") ;\par
        var i = 0 ;\par
        for ( i = 0 ; i < contacts.length ; i++ )\par
        \{\par
            var contact = new SocialContact(ccpSession, contacts[i]) ;\par
    \par
            var contactId = escape(contact.refUrl) ;\par
            conversation.urlToContactMap[contactId] = contact ;\par
            conversation.contactList[i] = contact ;\par
            \par
            var authorDiv = document.createElement("div") ;\par
            authorDiv.className = "author" ;\par
            authorDiv.innerHTML = contact.author ;\par
            authorDiv.setAttribute("id", CONTACT_AUTHOR_PREFIX + contactId) ;\par
            var titleDiv = document.createElement("div") ;\par
            titleDiv.className = "summary" ;\par
            \par
            var linkElement = document.createElement("a") ;\par
            linkElement.target = "_blank" ;\par
            linkElement.href = contact.link ;\par
            linkElement.innerHTML = contact.title ;\par
            linkElement.setAttribute("id", CONTACT_LINK_PREFIX + contactId) ;\par
            titleDiv.appendChild(linkElement) ;\par
            \par
            var descriptionDiv = document.createElement("div") ;\par
            descriptionDiv.innerHTML = contact.description ;\par
            descriptionDiv.setAttribute("id", CONTACT_DESCRIPTION_PREFIX + contactId) ;\par
            \par
            conversation.conversationDiv.appendChild(authorDiv) ;\par
            conversation.conversationDiv.appendChild(titleDiv) ;\par
            conversation.conversationDiv.appendChild(descriptionDiv) ;\par
            \par
            var actionDiv = document.createElement("div") ;\par
            actionDiv.setAttribute("class", "actionGroup") ;\par
            \par
            var escContactRef = escape(contact.refUrl) ;\par
            \par
            var replyActionId = REPLY_ACTION_PREFIX + escContactRef ;\par
            replyAction = conversation.createAction(replyActionId, conversation.prefs.getMsg('twitter_reply_reply_action')) ;\par
            replyAction.setAttribute("onclick", "showReplyDialog('" + escContactRef + "')") ;            \par
            actionDiv.appendChild(replyAction) ;\par
            \par
            if ( !contact.isDM )\par
            \{\par
                var retweetActionId = RETWEET_ACTION_PREFIX + escContactRef ;\par
                retweetAction = conversation.createAction(retweetActionId, conversation.prefs.getMsg('twitter_reply_retweet_action')) ;\par
                retweetAction.setAttribute("onclick", "showRetweetDialog('" + escContactRef + "')") ;\par
                actionDiv.appendChild(retweetAction) ;\par
            \}\par
            \par
            var dmActionId = DM_ACTION_PREFIX + escContactRef ;\par
            directMessageAction = conversation.createAction(dmActionId, conversation.prefs.getMsg('twitter_reply_dm_action')) ;\par
            directMessageAction.setAttribute("onclick", "showDirectMessageDialog('" + escContactRef + "')") ;\par
            \par
            actionDiv.appendChild(directMessageAction) ;\par
                \par
            conversation.conversationDiv.appendChild(actionDiv) ;\par
                    \par
            conversation.conversationDiv.style.overflow = "auto" ;\par
            \par
            conversation.updateActions(account) ;\par
        \}\par
    \}            \par
    this.ccpSession.getConversation(this.contactId, conversationCallback) ;\par
\}\par
\par
/**\par
 * This method is used to notify the conversation object that the account selected\par
 * on the reply template has changed.\par
 */\par
Conversation.prototype.updateActions = function(account)\par
\{\par
    var visibility = "visible" ;\par
    if ( account == null )\par
    \{\par
        visibility = "hidden" ;\par
    \}\par
\par
    this.setVisibility(visibility) ;    \par
\}\par
\par
/**\par
 * Hide the actions displayed in the conversation list\par
 */\par
Conversation.prototype.disable = function()\par
\{\par
    this.setVisibility("hidden") ;\par
\}\par
\par
/**\par
 * Show the actions displayed in the conversation list\par
 */\par
Conversation.prototype.enable = function()\par
\{\par
    this.setVisibility("visible") ;\par
\}\par
\par
/**\par
 * Set the visibility of the actions displayed in the conversation list\par
 */\par
Conversation.prototype.setVisibility = function(visibility)\par
\{\par
    var i = 0 ;\par
    for ( i = 0 ; i < this.contactList.length ; i++ )\par
    \{\par
        var contact = this.contactList[i] ;\par
        \par
        var escContactRef = escape(contact.refUrl) ;\par
        \par
        var retweetActionId = RETWEET_ACTION_PREFIX + escContactRef ;\par
        var action = document.getElementById(retweetActionId) ;\par
        if ( action != null )\par
        \{\par
            action.style.visibility = visibility ;\par
        \}\par
        \par
        var replyActionId = REPLY_ACTION_PREFIX + escContactRef ;\par
        action = document.getElementById(replyActionId) ;\par
        if ( action != null )\par
        \{\par
            action.style.visibility = visibility ;\par
        \}\par
        \par
        var dmActionId = DM_ACTION_PREFIX + escContactRef ;\par
        action = document.getElementById(dmActionId) ;\par
        if ( action != null )\par
        \{\par
            action.style.visibility = visibility ;\par
        \}\par
    \}\par
\}\par
\par
   \par
\par
//\par
// The following class manages the agent account selector and follow button on the reply template\par
//\par
\par
/**\par
 * Class used to manage agent account-related UI.\par
 */\par
function Agent(prefs, followButtonId, followAuthorId, agentSelectId)\par
\{\par
    this.author = null ;\par
    \par
    this.followButton = document.getElementById(followButtonId) ;\par
    this.followAuthor = document.getElementById(followAuthorId) ;\par
    this.agentSelect  = document.getElementById(agentSelectId) ;\par
    \par
    this.followingAuthorMap = [] ;\par
    \par
    this.prefs = prefs ;\par
\}\par
\par
/**\par
 * Set the author of the reserved contact\par
 */\par
Agent.prototype.setAuthor = function(author)\par
\{\par
    this.author = author ;\par
    \par
    if ( this.author != null )\par
    \{\par
        this.followAuthor.innerHTML = this.author ;\par
    \}\par
\}\par
\par
/**\par
 * Update the follow button based on whether the currently selected agent is\par
 * following the author of the reserved contact.\par
 */\par
Agent.prototype.updateFollowingUI = function(agent)\par
\{\par
    var following = this.followingAuthorMap[agent] ;\par
    if ( (following == null) || (following == undefined) )\par
    \{\par
        this.followButton.disabled = true ;\par
        \par
        return ;\par
    \}\par
\par
    this.followButton.disabled = false ;\par
    if ( following == false )\par
    \{\par
        this.followButton.value = this.prefs.getMsg('twitter_reply_follow') ;\par
        this.followButton.disabled = false ;\par
        this.followButton.onclick = follow ;\par
    \}\par
    else\par
    \{\par
        this.followButton.value = this.prefs.getMsg('twitter_reply_unfollow') ;\par
        this.followButton.disabled = false ;\par
        this.followButton.onclick = unfollow ;\par
    \}\par
\}\par
\par
/**\par
 * Determine if the given agent is following the author of the reserved contact.\par
 */\par
Agent.prototype.updateFollowing = function(newAgent)\par
\{\par
    if ( (this.author == null) || (newAgent == null) || (newAgent == this.author) )\par
    \{\par
        this.followButton.disabled = true ;\par
        \par
        return ;\par
    \}\par
    \par
    var following = this.followingAuthorMap[newAgent] ;\par
    if ( (following != null) && (following != undefined) )\par
    \{\par
        this.updateFollowingUI(newAgent) ;\par
        \par
        return ;\par
    \}\par
    \par
    followButton.disabled = true ;\par
    \par
    var agent = this ;\par
    var authorFriendshipsExistsCallback = function(response)\par
    \{\par
        agent.followingAuthorMap[newAgent] = null ;\par
\par
        if ( !handleRateLimit(response, newAgent) && (response.rc == 200) )\par
        \{\par
            var progress = getElementValue(response.data, PROGRESS_TAG) ;\par
            if ( progress != TWITTER_PROGRESS_FAILED )\par
            \{\par
                var friends = getElementValue(response.data, "friends") ;\par
                if ( friends != null )\par
                \{\par
                    if ( friends == "true" )\par
                    \{\par
                        agent.followingAuthorMap[newAgent] = true ;\par
                    \}\par
                    else\par
                    \{\par
                        agent.followingAuthorMap[newAgent] = false ;\par
                    \}\par
                \}   \par
            \}\par
        \}\par
            \par
        agent.updateFollowingUI(newAgent) ;\par
    \}\par
    ccpSession.twitterFriendshipExists(newAgent, newAgent, this.author, authorFriendshipsExistsCallback) ;\par
\}\par
\par
/**\par
 * The specified agent will follow the given author.\par
 */\par
Agent.prototype.follow = function(selectedAgent, author)\par
\{\par
    if ( (selectedAgent == null) || (author == null) )\par
    \{\par
        return ;\par
    \}\par
    \par
    if ( this.followButton.disabled )\par
    \{\par
        return ;\par
    \}\par
    \par
    this.followButton.disabled = true ;\par
    this.agentSelect.disabled = true ;\par
    \par
    var agent = this ;\par
    \par
    var followCallback = function(response)\par
    \{\par
        agent.followButton.disabled = false ;\par
        agent.agentSelect.disabled = false ;\par
    \par
        var error = getErrorDetails(response) ;\par
        if ( error != null )\par
        \{\par
            var errorMessage =\par
                agent.prefs.getMsg('twitter_reply_follow_failed') + " " + author + " " + agent.prefs.getMsg('twitter_reply_using') + " " + selectedAgent + "<br>" +\par
                error ;\par
            showError(errorMessage) ;\par
\par
            return ;                \par
        \}\par
        \par
        agent.followingAuthorMap[selectedAgent] = true ;\par
        agent.updateFollowingUI(selectedAgent) ;\par
    \}\par
    ccpSession.twitterFollow(selectedAgent, author, followCallback) ;\par
\}\par
\par
/**\par
 * The specified agent will no longer follow the given author.\par
 */\par
Agent.prototype.unfollow = function(selectedAgent, author)\par
\{\par
    if ( this.followButton.disabled )\par
    \{\par
        return ;\par
    \}\par
    \par
    this.followButton.disabled = true ;\par
    this.agentSelect.disabled = true ;\par
\par
    var agent = this ;\par
    \par
    var unfollowCallback = function(response)\par
    \{\par
        agent.followButton.disabled = false ;\par
        agent.agentSelect.disabled = false ;\par
        \par
        var error = getErrorDetails(response) ;\par
        if ( error != null )\par
        \{\par
            var errorMessage =\par
                agent.prefs.getMsg('twitter_reply_unfollow_failed') + " " + author + " " + agent.prefs.getMsg('twitter_reply_using') + " " + selectedAgent + "<br>" +\par
                error ;\par
            showError(errorMessage) ;\par
\par
            return ;                \par
        \}\par
        \par
        agent.followingAuthorMap[selectedAgent] = false ;\par
        agent.updateFollowingUI(selectedAgent) ;\par
    \}\par
    ccpSession.twitterUnfollow(selectedAgent, author, unfollowCallback) ;\par
\}\par
\par
/**\par
 * Disabled the follow button\par
 */\par
Agent.prototype.disable = function()\par
\{\par
    this.followButton.disabled = true ;\par
\}\par
\par
/**\par
 * Enable the follow button\par
 */\par
Agent.prototype.enable = function()\par
\{\par
    this.followButton.enabled = true ;\par
\}\par
   \par
\par
\par
//\par
// Constants\par
//\par
\par
// Type value of a CCP Twitter Account feed\par
// \par
var TWITTER_ACOUNT_TYPE = 6 ;\par
\par
// Maximum number of characters in a tweet\par
//\par
var MAX_TWEET_LEN = 140 ;\par
\par
var DIRECT_MESSAGE_PREFIX = "Direct message:" ;\par
\par
var ACCOUNT_NAME_KEY = "accountName" ;\par
\par
\par
// File-Scope Variables\par
//\par
var ccpSession   = null ;\par
var conversation = null ;\par
var profile      = null ;\par
var agent        = null ;\par
\par
var author = null ;\par
var timestamp = null ;\par
var contactId = null ;\par
\par
\par
// References to UI elements\par
//\par
var followButton = null ;\par
var accounts     = null ;\par
\par
\par
/**\par
* Hide the reply and set the social contact's state to nextState.\par
*/\par
function closeTemplate(nextState)\par
\{\par
    ccpSession.closeTemplate(nextState) ;\par
\}\par
\par
/**\par
 * Set the heading for the reply template\par
 */\par
function setHeading(heading)\par
\{\par
    ccpSession.setHeading(heading) ;\par
\}\par
\par
/**\par
* Show an error using the CCP infrastructure\par
*/\par
function showError(message)\par
\{\par
    ccpSession.showError(message) ;\par
\}\par
\par
/**\par
* Clear errors using the CCP infrastructure\par
*/\par
function clearError()\par
\{\par
    ccpSession.clearError() ;\par
\}\par
\par
/**\par
 * Return the value for the given key stored in the cookie\par
 */\par
function getFromCookie(key)\par
\{\par
\tab var keyEquals = key + "=" ;\par
\tab var cookies = document.cookie.split(';') ;\par
\tab for ( var i = 0 ; i < cookies.length ; i++ )\par
\tab\{\par
\tab\tab var cookie = cookies[i] ;\par
\tab\tab while ( cookie.charAt(0) == ' ')\par
\tab\tab\{\par
\tab\tab\tab cookie = cookie.substring(1, cookie.length) ;\par
\tab\tab\}\par
\tab\tab\par
\tab\tab if ( cookie.indexOf(keyEquals) == 0 )\par
\tab\tab\{\par
\tab\tab\tab return cookie.substring(keyEquals.length, cookie.length) ;\par
\tab\tab\}\par
\tab\}\par
\tab\par
\tab return null ;\par
\}\par
\par
/**\par
 * Trim excess content from the author's name. An author of a Twitter contact\par
 * should not contain spaces.\par
 */\par
function trimAuthor(author)\par
\{\par
    if ( author != null )\par
    \{\par
        var space = author.indexOf(' ') ;\par
        if ( space != -1 )\par
        \{\par
            author = author.substring(0, space) ;\par
        \}\par
    \}\par
\par
    return author ;\par
\}        \par
\par
/*\par
 * This function parses the date and formats it so that it works for IE\par
 * Twitter sends a weird date String like "Thu Feb 17 23:18:36 +0000 2011"\par
 * wherein the year is after the timezone. So rearraging and some tweaks to timezone makes it work for all browsers\par
 * The rearranged dateString looks like "Thu Feb 17 2011 23:18:36 UTC"\par
 */\par
function fixDateFormat(dateString) \par
\{\par
  var p = dateString.split(' ');\par
  return new Date(Date.parse(p[1]+" "+p[2]+", "+p[5]+" "+p[3]+" UTC"));\par
\} \par
\par
/*\par
 * Returns a formatted time for the given date string in the format "Thu Feb 17 23:18:36 +0000 2011"\par
 */\par
function formattedDate(dateString)\par
\{\par
    var date = fixDateFormat(dateString);\par
    var hours = date.getHours();\par
    var minutes = date.getMinutes();\par
    var amPM = (hours > 11)? "__MSG_twitter_reply_pm__": "__MSG_twitter_reply_am__";\par
    if ( hours != 12 )\par
    \{\par
        hours = hours % 12;\par
    \}\par
    minutes = (minutes < 10)? "0"+minutes : minutes;\par
    hours = (hours < 10)? "0"+hours : hours;\par
    var result = hours + ":" + minutes + " " + amPM;\par
    return result;\par
\}\par
\par
/**\par
 * Check to see if the given response indicates that the account has been\par
 * rate-limited by Twitter.  If the account has been rate-limited, disable\par
 * the UI and display an error message.  Otherwise, enable the UI.\par
 */\par
var rateLimited = false ;\par
\par
/**\par
 * Check the response to a reply API message to see if Twitter is rate limited\par
 * the given account or the system.\par
 *\par
 * If twitterAccount is null, a message will be displayed stating the system is\par
 * rate limited. Otherwise, a message stating the account is rate limitied will\par
 * be displayed.\par
 */\par
function handleRateLimit(responseObj, twitterAccount)\par
\{\par
    var wasRateLimited = rateLimited ;\par
    \par
    rateLimited = getElementValue(responseObj.data, RATE_LIMITED_TAG) == "true" ;\par
    if ( !rateLimited )\par
    \{\par
        if ( wasRateLimited )\par
        \{            \par
            clearError() ;\par
            disableUI(false) ;\par
        \}\par
        \par
        return false ;\par
    \}\par
\par
    if ( !wasRateLimited )\par
    \{\par
        disableUI(true) ;\par
            \par
        var rateLimitEndDate = getElementValue(responseObj.data, HTTP_RESPONSE_MSG_TAG) ;\par
        log("End date: " + rateLimitEndDate) ;\par
        \par
        var errorMsg = "" ;\par
        if ( (twitterAccount == null) )\par
        \{\par
            errorMsg = "__MSG_twitter_reply_system_rate_limited__" ;\par
            errorMsg = errorMsg + "<br>__MSG_twitter_reply_system_rate_limited_until__ " + formattedDate(rateLimitEndDate) ;\par
        \}\par
        else\par
        \{\par
            errorMsg = "__MSG_twitter_reply_account_rate_limited__ " + twitterAccount ;\par
            errorMsg = errorMsg + "<br>__MSG_twitter_reply_account_rate_limited_until__ " + formattedDate(rateLimitEndDate) ;\par
        \}\par
        showError(errorMsg) ;\par
    \}\par
    \par
    return true ;\par
\}\par
\par
/**\par
 * Get the erorr-related details of a response to a reply API message.\par
 * Null is returned if the operation was successful.\par
 */\par
function getErrorDetails(response)\par
\{\par
    if ( response.rc != 200 )\par
    \{\par
        return "__MSG_twitter_reply_error__ " + response.rc ;\par
    \}\par
\par
    var progress = getElementValue(response.data, PROGRESS_TAG) ;\par
    if ( progress == TWITTER_PROGRESS_FAILED )\par
    \{\par
        var error =\par
            "__MSG_twitter_reply_twitter_error__ " + getElementValue(response.data, "httpResponseCode") + "<br>" +\par
            "__MSG_twitter_reply_twitter_message__ " + getElementValue(response.data, "httpResponseMessage") ;\par
            \par
        return error ;\par
    \}\par
    \par
    return null ;\par
\}\par
\par
/**\par
 * Disable the reply template UI. This is done when the account is rate-limited.\par
 */\par
function disableUI(disabled)\par
\{\par
    if ( disabled )\par
    \{\par
        agent.disable() ;\par
        conversation.disable() ;\par
    \}\par
    else\par
    \{\par
        clearError() ;\par
        \par
        agent.enable() ;\par
        conversation.enable() ;\par
    \}    \par
\}\par
\par
/**\par
 * Set the given key/value pair in the cookie\par
 */\par
function setInCookie(key, value)\par
\{\par
\tab var curDate = new Date() ;\par
\tab\par
\tab // Expire in 30 days\par
\tab //\par
\tab var expiresDate = new Date(curDate.getTime() + (1000 * 60 * 60 * 24 * 30)) ;\par
\tab document.cookie = key + "=" + value + "; expires=" + expiresDate.toGMTString() + "; path=/" ;\par
\}\par
\par
/**\par
 * Show the given progress message\par
 */\par
function showProgressMessage(message)\par
\{\par
    var progressDiv = document.getElementById("progress") ;\par
    progressDiv.style.height = this.innerHeight + "px" ;\par
    progressDiv.style.width = this.innerWidth + "px" ;\par
    \par
    var messageSpan = document.getElementById("progressSpan") ;\par
    messageSpan.innerHTML = message ;\par
\par
    var border = document.getElementById("progressMessage") ;\par
    \par
    border.style.top = (this.innerHeight / 2) - (border.offsetHeight / 2) + "px" ;\par
    border.style.left = (this.innerWidth / 2) - (border.offsetWidth / 2) + "px" ;\par
    \par
    progressDiv.style.visibility = "visible" ;  \par
\}\par
\par
/**\par
 * Hide the progress message\par
 */\par
function hideProgressMessage()\par
\{\par
    var progressDiv = document.getElementById("progress") ;\par
    progressDiv.style.visibility = "hidden" ;  \par
\}\par
\par
/**\par
 * Send a reply using the selectedAccount.  The text in the reply area is used\par
 * as the text of the message.\par
 */\par
function retweet(tweetId)\par
\{\par
    var selectedAccount = accounts.options[accounts.selectedIndex].value ;\par
    \par
    showProgressMessage("__MSG_twitter_reply_retweet_progress__") ;\par
    \par
    var retweetCallback = function(response)\par
    \{\par
        hideProgressMessage() ;\par
        \par
        var error = getErrorDetails(response) ;\par
        if ( error != null )\par
        \{\par
            var errorMessage = "__MSG_twitter_reply_retweet_failed__ " + selectedAccount + "<br>" + error ;\par
            showError(errorMessage) ;\par
            \par
            return ;\par
        \}\par
\par
        setInCookie(ACCOUNT_NAME_KEY, selectedAccount) ;\par
\par
        closeTemplate(SC_STATUS_HANDLED) ;\par
    \}\par
    ccpSession.twitterRetweet(selectedAccount, tweetId, retweetCallback) ;\par
\}\par
\par
/**\par
 * Retweet the tweet with the given ID\par
 */\par
function sendRetweet(tweetId)\par
\{    \par
    closeDialog() ;\par
\par
    showProgressMessage("__MSG_twitter_reply_retweet_progress__") ;\par
    \par
    retweet(tweetId) ;\par
\}\par
\par
/**\par
 * Display the social contact with the given ID in the retweet dialog\par
 */\par
function showRetweetDialog(contactId)\par
\{\par
    setDraggableDialog("draggableDialogHeader", "retweetDialog") ;\par
    \par
    var contact = conversation.urlToContactMap[contactId] ;\par
    \par
    document.getElementById("retweetDialog_header").innerHTML = "__MSG_twitter_reply_retweet_title__" ;\par
    document.getElementById("retweetDialog_author").innerHTML = contact.author ;\par
    \par
    if ( isEmptyString(contact.description) )\par
    \{\par
        document.getElementById("retweetDialog_description").innerHTML = contact.title ;\par
    \}\par
    else\par
    \{\par
        document.getElementById("retweetDialog_description").innerHTML = contact.description ;\par
    \}\par
    \par
    document.getElementById("retweetDialog_sendButton").setAttribute("onclick", "sendRetweet('" + contact.tweetId + "')") ;\par
    \par
    openDialog() ;\par
\}\par
\par
/**\par
 * Send a reply using the selectedAccount.  The text in the reply area is used\par
 * as the text of the message.\par
 */\par
function reply(selectedAccount, message, tweetId)\par
\{\par
    var replyCallback = function(response)\par
\tab\{\par
\tab     hideProgressMessage() ;\par
\par
        var error = getErrorDetails(response) ; \par
        if ( error != null )\par
        \{\par
            var errorMessage = "__MSG_twitter_reply_reply_failed__ " + selectedAccount + "<br>" + error ;\par
            showError(errorMessage) ;\par
            \par
            return ;\par
        \}\par
\par
\tab\tab setInCookie(ACCOUNT_NAME_KEY, selectedAccount) ;\par
\par
\tab\tab closeTemplate(SC_STATUS_HANDLED) ;\par
\tab\}\par
\tab ccpSession.twitterReply(selectedAccount, message, tweetId, replyCallback) ;\par
\}\par
\par
/**\par
 * Reply to the given tweet\par
 */\par
function sendReply(tweetId)\par
\{    \par
    closeDialog() ;\par
\par
    showProgressMessage("__MSG_twitter_reply_reply_progress__") ;\par
    \par
    var selectedAccount = accounts.options[accounts.selectedIndex].value ;\par
    \par
    reply(selectedAccount, document.getElementById("replyDialog_text").value, tweetId) ;\par
\}\par
\par
/**\par
 * Display the reply dialog with the social contact with the specified ID\par
 */\par
function showReplyDialog(contactId)\par
\{\par
    setDraggableDialog("draggableDialogHeader", "replyDialog") ;\par
    \par
    var contact = conversation.urlToContactMap[contactId] ;\par
    \par
    var contactAuthor = trimAuthor(contact.author) ;\par
    \par
    var replyPrefix = "@" + contactAuthor ;\par
    document.getElementById("replyDialog_header").innerHTML = "__MSG_twitter_reply_reply_title__ " + replyPrefix ;\par
    document.getElementById("replyDialog_text").value = replyPrefix + " " ;\par
    document.getElementById("replyDialog_author").innerHTML = contactAuthor ;\par
    \par
    if ( isEmptyString(contact.description) )\par
    \{\par
        document.getElementById("replyDialog_description").innerHTML = contact.title ;\par
    \}\par
    else\par
    \{\par
        document.getElementById("replyDialog_description").innerHTML = contact.description ;\par
    \}\par
    \par
    document.getElementById("replyDialog_sendButton").setAttribute("onclick", "sendReply('" + contact.tweetId + "')") ;\par
    updateCharactersLeft("replyDialog_text", "replyDialog_charactersLeft", "replyDialog_sendButton") ;\par
    \par
    openDialog() ;\par
\}\par
\par
/**\par
 * Send a direct message using the selectedAccount.  The author of the social\par
 * contact is the target of the direct message.  The text in the reply area is\par
 * used as the text of the message.\par
 */\par
function directMessage(selectedAccount, contactAuthor, message)\par
\{\par
\tab var directMessageCallback = function(response)\par
\tab\{\par
        hideProgressMessage() ;\par
        \par
        var error = getErrorDetails(response) ; \par
        if ( error != null )\par
        \{\par
            var errorMessage = "__MSG_twitter_reply_dm_failed__ " + selectedAccount + "<br>" + error ;\par
            showError(errorMessage) ;\par
            \par
            return ;\par
        \}\par
\par
\tab\tab setInCookie(ACCOUNT_NAME_KEY, selectedAccount) ;\par
\par
        closeTemplate(SC_STATUS_HANDLED) ;\par
\tab\}\par
\tab ccpSession.twitterDirectMessage(selectedAccount, contactAuthor, message, directMessageCallback) ;\par
\}\par
\par
/**\par
 * Send a direct message to the specified author\par
 */\par
function sendDirectMessage(contactAuthor)\par
\{    \par
    closeDialog() ;\par
\par
    showProgressMessage("__MSG_twitter_reply_dm_progress__") ;\par
    \par
    var selectedAccount = accounts.options[accounts.selectedIndex].value ;\par
    \par
    contactAuthor = trimAuthor(contactAuthor) ;\par
    \par
    directMessage(selectedAccount, contactAuthor, document.getElementById("dmDialog_text").value) ;\par
\}\par
\par
/**\par
 * Show the direct message dialog based on the social contact with the given ID\par
 */\par
function showDirectMessageDialog(contactId)\par
\{\par
    setDraggableDialog("draggableDialogHeader", "dmDialog") ;\par
    \par
    var contact = conversation.urlToContactMap[contactId] ;\par
    \par
    document.getElementById("dmDialog_header").innerHTML = "__MSG_twitter_reply_dm_title__ " + contact.author ;\par
    document.getElementById("dmDialog_text").value = "" ;\par
    document.getElementById("dmDialog_sendButton").setAttribute("onclick", "sendDirectMessage('" + contact.author + "')") ;\par
    updateCharactersLeft("dmDialog_text", "dmDialog_charactersLeft", "dmDialog_sendButton") ;\par
    \par
    openDialog() ;\par
\}\par
\par
/**\par
 * Make sure the text in the reply area is within Twitter's limits.\par
 */\par
function updateCharactersLeft(textAreaId, charsLeftId, sendButtonId)\par
\{\par
    var textLength = document.getElementById(textAreaId).value.length ;\par
    if ( (textLength <= 0) || (textLength > MAX_TWEET_LEN) )\par
    \{\par
        document.getElementById(sendButtonId).disabled = true ;\par
    \}\par
    else\par
    \{\par
        document.getElementById(sendButtonId).disabled = false ;\par
    \}\par
    \par
    var charsLeft = MAX_TWEET_LEN - document.getElementById(textAreaId).value.length ;\par
\tab document.getElementById(charsLeftId).innerHTML = charsLeft ;\par
\}\par
\par
/**\par
 * Get the currently selected account\par
 */\par
function getSelectedAccount()\par
\{\par
    var account = null ;\par
    if ( accounts.selectedIndex > 0 )\par
    \{\par
        account = accounts.options[accounts.selectedIndex].value ;\par
    \}\par
    \par
    return account ;\par
\}\par
\par
/**\par
 * HTML UI callbacks\par
 */\par
 \par
/**\par
 * Process changes to the account pulldown\par
 */\par
function accountChanged()\par
\{\par
    var account = getSelectedAccount() ;    \par
    if ( account != null )\par
    \{\par
        setInCookie(ACCOUNT_NAME_KEY, account) ;\par
    \}\par
    \par
\tab conversation.updateActions(account) ;\par
\tab profile.updateFollowing(account) ;\par
\tab agent.updateFollowing(account) ;\par
\}\par
\par
/**\par
 * Follow the author of the social contact\par
 */\par
function follow()\par
\{\par
\tab if ( accounts.selectedIndex == 0 )\par
\tab\{\par
\tab\tab return ;\par
\tab\}\par
\tab\par
\tab agent.follow(accounts.options[accounts.selectedIndex].value, author) ;\par
\}\par
\par
/**\par
 * Unfollow the author of the social contact\par
 */\par
function unfollow()\par
\{\par
    if ( accounts.selectedIndex == 0 )\par
    \{\par
        return ;\par
    \}\par
    \par
    agent.unfollow(accounts.options[accounts.selectedIndex].value, author) ;\par
\}\par
\par
/**\par
 * Store the details of the given social contact response\par
 */\par
function updateWithSocialContact(response)\par
\{\par
    var contact = response.data ;\par
    author = getElementValue(contact, "author") ;\par
    author = trimAuthor(author) ;\par
        \par
    if ( (author == null) || (author.length == 0) )\par
    \{\par
        followButton.style.visibility = "hidden" ;\par
    \}\par
        \par
    contactId = getElementValue(contact, "id") ;\par
        \par
    timestamp = getElementValue(contact, "statusTimestamp") ;\par
\}\par
\par
/**\par
 * Update the UI (mainly the account selector) with the given list of accounts\par
 */\par
function updateWithAccounts(response)\par
\{\par
    var feeds = response.data.getElementsByTagName("Feed") ;\par
    if ( feeds == null )\par
    \{\par
        return ;\par
    \}\par
            \par
    var ccpAccounts = [] ;\par
    for ( var i = 0 ; i < feeds.length ; i++ )\par
    \{\par
        var feedType = feeds[i].getElementsByTagName("type")[0].firstChild.nodeValue ;\par
                    \par
        if ( feedType == TWITTER_ACOUNT_TYPE )\par
        \{\par
            ccpAccounts[ccpAccounts.length] =\par
                feeds[i].getElementsByTagName("authenticationUsername")[0].firstChild.nodeValue ;\par
        \}\par
    \}\par
            \par
    var selectedAccount = getFromCookie(ACCOUNT_NAME_KEY) ;\par
    accounts[accounts.length] = new Option("", "") ;\par
            \par
    for ( var i = 0 ; i < ccpAccounts.length ; i++ )\par
    \{\par
        accounts[accounts.length] = new Option(ccpAccounts[i], ccpAccounts[i]) ;\par
        if ( ccpAccounts[i] == selectedAccount )\par
        \{\par
            accounts.selectedIndex = accounts.length - 1 ;\par
        \}\par
    \}\par
            \par
    accounts.disabled = false ;\par
\}\par
\par
/**\par
 * onLoad() entry point into the reply template\par
 */\par
function main()\par
\{\par
    followButton   = document.getElementById("followButton") ;\par
    accounts       = document.getElementById("accounts") ;\par
    \par
    ccpSession = new CcpSession(window.location.href) ;\par
    conversation = new Conversation(ccpSession, "conversation") ;\par
    profile = new Profile(ccpSession,\par
                    "profileName", "profileImage", "profileDescription",\par
                    "profileUrl", "profileFollowersCount", "profileFollowingAgent") ;\par
    agent = new Agent(ccpSession.prefs, "followButton", "followAuthor", "accounts") ;\par
    \par
    setHeading("Twitter Reply") ;\par
\par
    var urls = [] ;\par
    urls[0] = ccpSession.restSocialContact ;\par
    urls[1] = ccpSession.restGetFeedList ;\par
    \par
    var contactCallback = function(response)\par
    \{\par
        if ( response.rc != 200 )\par
        \{\par
            showError(\par
                "__MSG_twitter_reply_get_contact_failed__<br>" +\par
                "__MSG_twitter_reply_error_code__ " + response.rc + "<br>" +\par
                "__MSG_twitter_reply_error_message__ " + response.text) ;\par
        \par
            return ;\par
        \}\par
        \par
        updateWithSocialContact(response) ;\par
\par
        var feedsCallback = function(response)\par
        \{\par
            if ( response.rc != 200 )\par
            \{\par
                showError(\par
                    "__MSG_twitter_reply_get_accounts_failed__<br>" +\par
                    "__MSG_twitter_reply_error_code__ " + response.rc + "<br>" +\par
                    "__MSG_twitter_reply_error_message__ " + response.text) ;\par
                \par
                return ;\par
            \}\par
            \par
            updateWithAccounts(response) ;\par
            \par
            var account = getSelectedAccount() ;\par
            var oauthAccount = account ;\par
            if ( (oauthAccount == null) && (accounts.length > 1) )\par
            \{\par
                oauthAccount = accounts[1].value ; \par
            \}\par
            conversation.populate(contactId, account) ;\par
            profile.populate(author, account, oauthAccount) ;\par
            agent.setAuthor(author) ;\par
            agent.updateFollowing(account) ;\par
        \}        \par
        ccpSession.getAllCcpFeeds(feedsCallback) ;\par
    \}\par
    ccpSession.getSocialContact(contactCallback) ;\par
\}\par
\par
</script>\par
\par
</head>\par
\par
<body onLoad="main()">\par
<div id="reply"  style="width:50%">\par
  <!-- Profile -->\par
  <div>\par
    <div><label id="profileName" class="profileName"></label></div>\par
  <div>\par
  <div class="profilePicture">\par
    <img id="profileImage"/>\par
   <img src="AIS_logo.jpg" alt="AIS logo" /> \par
  </div>\par
  <div class="profile">\par
    <div id="profileDescription" class="profileText"></div>\par
      <div class="profileUrl">\par
        <a id="profileUrl" target="_blank" href="javascript:void(0)">\par
      </div>\par
      <div class="profileText">\par
        <span id="profileFollowersCount"></span>\par
      </div>\par
      <div class="profileText">\par
        <span id="profileFollowingAgent"></span>\par
      </div>              \par
    </div>\par
  </div>\par
  \par
  <!-- Follow and account collection -->\par
  <div>\par
      <div style="padding-top: 10px;">\par
          <div style="float:left;">\par
              <label>__MSG_twitter_reply_account__&nbsp</label>\par
              <select id="accounts" tabindex=1 onchange="javascript:accountChanged()">\par
              </select>\par
          </div>\par
          <div style="float:left; margin-left:60px">\par
              <input id="followButton" type="button" value="__MSG_twitter_reply_follow__" disabled="true" onclick="javascript:follow()">\par
              <span id="followAuthor"></span>\par
          </div>\par
      </div>\par
  </div>  \par
  \par
  <!-- Conversation -->\par
  <div id="conversation" class="conversation"/></div>\par
  \par
  <!-- Reply dialog -->\par
  <div id="replyDialog" class="draggableDialog">\par
    <div id="replyDialog_header" class="draggableDialogHeader"></div>\par
    <div class="closeDialog">\par
      <b id="replyDialogClose" onclick="closeDialog()">x</b>\par
    </div>\par
    <div class="innerDialog">\par
      <div>\par
        <textarea id="replyDialog_text" class="tweetArea"\par
          onchange="javascript:updateCharactersLeft('replyDialog_text', 'replyDialog_charactersLeft', 'replyDialog_sendButton')"\par
          onkeyup="javascript:updateCharactersLeft('replyDialog_text', 'replyDialog_charactersLeft', 'replyDialog_sendButton')"\par
          onkeypress="javascript:updateCharactersLeft('replyDialog_text', 'replyDialog_charactersLeft', 'replyDialog_sendButton')">\par
        </textarea>\par
      </div>\par
      <div class="dialogButtons">\par
        <label id="replyDialog_charactersLeft" class="countDown">140</label>\par
        <input id="replyDialog_sendButton" class="tweetButton" type="button" value="__MSG_twitter_reply_tweet__">\par
      </div>\par
      <div class="repliedToTweet">\par
        <div id="replyDialog_author" class="authorSmall"></div>\par
        <div id="replyDialog_description" class="descriptionSmall"></div>\par
      </div>\par
    </div>\par
  </div>\par
  \par
  <!-- Retweet dialog -->\par
  <div id="retweetDialog" class="draggableDialog">\par
    <div id="retweetDialog_header" class="draggableDialogHeader"></div>\par
    <div class="closeDialog">\par
      <b id="retweetDialogClose" onclick="closeDialog()">x</b>\par
    </div>\par
    <div class="innerDialog">\par
      <div class="retweetedTweet">\par
        <div id="retweetDialog_author" class="authorSmall"></div>\par
        <div id="retweetDialog_description" class="descriptionSmall"></div>\par
      </div>\par
      <div class="dialogButtons">\par
        <input id="retweetDialog_sendButton" class="tweetButton" type="button" value="__MSG_twitter_reply_retweet__">\par
      </div>\par
    </div>\par
  </div>\par
  \par
  <!-- Direct message dialog -->\par
  <div id="dmDialog" class="draggableDialog">\par
    <div id="dmDialog_header" class="draggableDialogHeader"></div>\par
    <div class="closeDialog">\par
      <b id="dmDialogClose" onclick="closeDialog()">x</b>\par
    </div>\par
    <div class="innerDialog">\par
      <div>\par
        <textarea id="dmDialog_text" class="tweetArea"\par
          onchange="javascript:updateCharactersLeft('dmDialog_text', 'dmDialog_charactersLeft', 'dmDialog_sendButton')"\par
          onkeyup="javascript:updateCharactersLeft('dmDialog_text', 'dmDialog_charactersLeft', 'dmDialog_sendButton')"\par
          onkeypress="javascript:updateCharactersLeft('dmDialog_text', 'dmDialog_charactersLeft', 'dmDialog_sendButton')">\par
        </textarea>\par
      </div>\par
      <div class="dialogButtons">\par
        <label id="dmDialog_charactersLeft" class="countDown">140</label>\par
        <input id="dmDialog_sendButton" class="tweetButton" type="button" value="__MSG_twitter_reply_send__">\par
      </div>\par
    </div>\par
  </div>\par
  \par
  <div id="progress" class="progressLayer">\par
    <div id="progressMessage" class="progressMessage">\par
      <span id="progressSpan" class="progressSpan"></span>\par
    </div>\par
  </div>\par
</div>\par
\par
</body>\par
</html>    \par
  ]]>\par
  </Content>\par
</Module>\par
\par
\par
}
 